x <- 1:100
w <- 1/20
sin(2*pi*w * x + 1/2) + cos(2*pi*w* x + 10*3.3412) |> plot()
numeric(0)

Вспомогательные функции

library(Rssa)
Загрузка требуемого пакета: svd
Загрузка требуемого пакета: forecast

Присоединяю пакет: ‘Rssa’

Следующий объект скрыт от ‘package:stats’:

    decompose
library(signal)

Присоединяю пакет: ‘signal’

Следующий объект скрыт от ‘package:Rssa’:

    roots

Следующие объекты скрыты от ‘package:stats’:

    filter, poly
library(gsignal)
Registered S3 methods overwritten by 'gsignal':
  method         from  
  plot.grpdelay  signal
  plot.specgram  signal
  print.freqs    signal
  print.freqz    signal
  print.grpdelay signal
  print.impz     signal
  print.specgram signal

Присоединяю пакет: ‘gsignal’

Следующий объект скрыт от ‘package:signal’:

    Arma, as.Arma, as.Zpg, bartlett, bilinear, blackman, boxcar, butter, buttord, cheb1ord, chebwin, cheby1, cheby2, chirp, conv,
    decimate, ellip, ellipord, fftfilt, filter, filtfilt, fir1, fir2, flattopwin, freqs, freqs_plot, freqz, freqz_plot, gausswin,
    grpdelay, hamming, hanning, ifft, impz, interp, kaiser, kaiserord, levinson, Ma, medfilt1, poly, remez, resample, sftrans, sgolay,
    sgolayfilt, specgram, triang, unwrap, Zpg, zplane

Следующие объекты скрыты от ‘package:stats’:

    filter, gaussian, poly
source("eossa_new.R")


dftmtx <- function(n) {
  y <- stats::mvfft(diag(1, n))
  y
}

diag_averaging <- function(A){
  B <- A[nrow(A):1, ] |> Re()
  lapply(split(B, -(row(B) - col(B)) ), mean) |> as.numeric()
}

shift_vector <- function(vec) {
  last_element <- tail(vec, 1)
  vec <- vec[-length(vec)]
  shifted_vec <- c(last_element, vec)
  return(shifted_vec)
}

extend <- function(x, H){
  # Вычисление коэффициентов AR модели для дифференцированного ряда
  N <- length(x)
  p <- floor(N / 3)
  dx <- diff(x)
  # A <- ar(dx, order.max = p, method = "yule-walker")$ar
  A <- aryule(dx, p)$a
  
  # Правое расширение
  y <- x
  dy <- diff(y)
  er <- signal::filter(A, 1, dy)
  dy <- signal::filter(1, A, c(er, rep(0, H)))
  y <- y[1] + c(0, cumsum(dy))
  
  # Левое расширение
  y <- rev(y)
  dy <- diff(y)
  er <- signal::filter(A,1,dy)
  dy <- signal::filter(1,A,c(er, rep(0, H)))
  y <- y[1] + c(0, cumsum(dy))
  
  # Расширенный ряд
  xe <- rev(y)
  
  # Вывод результатов
  xe 
}

CiSSA

Подаётся на вход временной ряд, длина окна (если её нет, то она равна длине ряда + 1 пополам) и информация о том, нужно ли расширить ряд. Расширять ряд стоит при стохастическом тренде (Autoregressive extension (default). It is indicated for stationary and stochastic trend time series as well). Реализовано только Autoregressive extension.


На выходе список выдаётся список list(t_series, importance).
t_series — матрица, по столбцам которой располагаются временные ряды, отвечающие за частоты (i-1)/L, где i — номер столбца, L — длина окна.
importance — вектор, отвечающий за значимость i-ого временного ряда в разлолжении. Чем больше значение, тем больший вклад внёс i-тый временной ряд.

circulant_SSA <- function(ts, L = NULL, extend_flag = FALSE){
  time_series <- ts
  # Construct trajectory matrix
  N <- length(time_series)
  if (is.null(L)){
    L <- (N + 1)%/%2
  }
  # Проверка на расширения ряда
  if (extend_flag == FALSE){
    H <- 0
    time_series <- ts
  }
  else{
    H <- L
    time_series <- extend(ts, H)
  }
  
  X <- hankel(time_series, L)
  
  # Number of symmetric frequency pairs around 1/2
  if (L %% 2) {
    nf2 <- (L + 1) / 2 - 1
  } else {
    nf2 <- L / 2 - 1
  }
  
  # Number of frequencies <= 1/2
  nft <- nf2 + abs((L %% 2) - 2)
  
  # Decomposition
  # Estimate autocovariance     OK
  autocov <- numeric(L)
  for (m in 0:(L-1)){
    autocov[[m+1]] <- sum(time_series[1:(N-m)] * time_series[(1+m):N]) / (N-m)
  }
  
  # First row of circulant matrix
  circ_first_row <- numeric(L)
  for (m in 0:(L-1)){
    circ_first_row[[m+1]] <- (L-m)/L * autocov[[m+1]] + (m)/L * autocov[[L-m]]
  }
  
  # Build circulant matrix
  S_C <- matrix(circ_first_row, nrow = 1)
  shifted_vector <- circ_first_row
  for (i in 2:(L)) {
    shifted_vector <- shift_vector(shifted_vector)
    # S_C <- rbind(S_C, as.vector(shifted_vector))
    S_C <- rbind(as.vector(shifted_vector), S_C)
  }
  
  # Eigenvectors of circulant matrix (unitary base)
  U <- dftmtx(L)/sqrt(L)
  
  # Real eigenvectors (orthonormal base)
  U[, 1] <- Re(U[, 1])
  for (k in 1:nf2) {
    u_k <- U[, k + 1]
    U[, k + 1] <- sqrt(2) * Re(u_k)
    U[, L + 2 - (k + 1)] <- sqrt(2) * Im(u_k)
  }
  if (L %% 2 != 0) {
    U[, nft] <- Re(U[, nft])
  }
  
  # Eigenvalues of circulant matrix: estimated power spectral density
  psd <- abs(diag(t(U) %*% S_C %*% U))
  
  # Principal components
  W <- t(U) %*% X
  # Reconstruction
  # Elementary reconstructed series
  R <- matrix(0, nrow = N+2*H, ncol = L)
  for (k in 1:L) {
    R[, k] <- U[ ,k] %*% t(W[k, ]) |> diag_averaging()
  }
  
  # Grouping by frequency
  # Elementary reconstructed series by frequency
  Z <- matrix(0, nrow = N+2*H, ncol = nft)
  Z[, 1] <- R[, 1]
  # Importance of component
  imp <- numeric(nft)
  lambda_sm <- sum(psd)
  imp[1] <- psd[1]/lambda_sm
  for (k in 1:nf2) {
    Z[, k + 1] <- R[, k + 1] + R[, L + 2 - (k + 1)]
    imp[k+1] <- (psd[k+1] + psd[ L + 2 - (k + 1)])/lambda_sm
  }
  if (L %% 2 != 0) {
    Z[, nft] <- R[, nft]
    imp[nft] <- psd[nft] / lambda_sm
  }
  
  list(t_series = Z[(H+1):(N+H),],
       importance = imp,
       freq = (0:(length(imp) -1))/L
       )
}
# groups - list of frequencies
grouping_cissa <- function(cissa_res, groups){
  freq <- cissa_res$freq
  t_series <- cissa_res$t_series
  
  
  residuals <- 0
  result <- setNames(as.list(rep(0, length(groups))), names(groups))
  result_freqs <- list()
  for (i in 1:length(cissa_res$freq)){
    flag <- FALSE
    for (name in names(groups)){
      if (groups[[name]][1] <= freq[i] & freq[i] <= groups[[name]][2]){
        flag <- TRUE
        result[[name]] <- result[[name]] + t_series[, i]
        result_freqs[[name]] <- c(result_freqs[[name]], freq[i])
      }
    }
    
    if (flag == FALSE){
      residuals <- residuals + t_series[, i]
    }
  }
  
  result[["residuals"]] <- residuals
  
  return(
    list(
      t_series = result,
      freqs_by_group = result_freqs
    )
  )
  result
}
generate_ts <- function(func, n=1e3, ...){
  1:n |> func(...) |> ts()
}

f_cos <- function(x, A = 1, omega = 1/4, phi = 0){
  f_exp_mod_harm_series(x, A, alpha = 0, omega = omega, phi = phi)
}

f_sin <- function(x, A = 1, omega = 1/4, phi = 3*pi/2){
  f_exp_mod_harm_series(x, A, alpha = 0, omega = omega, phi = phi)
}

f_exp <- function(x, A = 1, alpha = 1){
  A * exp(alpha * x)
}

f_exp_cos <- function(x, A = 1, alpha = 1, omega = 1/4, phi = 0){
  f_exp_mod_harm_series(x, A, alpha, omega, phi)
}

f_const <- function(x, C = 0){
  rep(C, length(x))
}

f_exp_mod_harm_series <- function(x, A = 1, alpha = 1, omega = 1/4, phi = 0){
  A*exp(alpha*x)*cos(2*pi*omega*x + phi)
}

f_linear <- function(x, a = 1, b = 0){
  a*x + b
}
mse <- function(f_true, f_reconstructed){
   mean((f_true - f_reconstructed)^2) 
}

Ошибка при Lw in N, Kw not in N

n <- 96*2+5
L <- 96
eps <- 1/97
f_sum <- function(x){
  f_const(x, C = 1) + f_cos(x, omega = 1/12) 
}


f_const |> generate_ts(n, C = 1) |>
  plot(col = "green", ylim = c(-1, 2), ylab = "f_n")
f_cos |>
  generate_ts(n, omega = 1/12) |>
  lines(col="green")
f_sum |> generate_ts(n) |> lines(lwd = 3, col='red')
f_n <- f_sum(1:n)



c <- circulant_SSA(f_n, L = 96, extend_flag = FALSE)
r <- grouping_cissa(c,
               groups = list(
                 trend = c(0, eps),
                 sesonal = c(1/12-eps, 1/12 + eps)
               )
               )$t_series

f_C <- f_const |> generate_ts(n, C = 1)
f_c <- f_cos |> generate_ts(n, omega = 1/12)
print("Ошибки при CiSSA")
[1] "Ошибки при CiSSA"
print(paste("Ошибка при вычислении C = 1: ", mse(f_C, r$trend) |> format(scientific = TRUE, digits = 2) ))
[1] "Ошибка при вычислении C = 1:  3.2e-31"
print(paste("Ошибка при вычислении cos(pi/12): ", mse(f_c, r$sesonal) |> format(scientific = TRUE, digits = 2) ))
[1] "Ошибка при вычислении cos(pi/12):  5.1e-30"
lines(1:n, r$trend, col="blue")
lines(1:n, r$sesonal, col="blue")


f_const |> generate_ts(n, C = 1) |>
  plot(col = "green", ylim = c(-1, 2), ylab = "f_n")
f_cos |>
  generate_ts(n, omega = 1/12) |>
  lines(col="green")
f_sum |> generate_ts(n) |> lines(lwd = 3, col='red')
f_n <- f_sum(1:n)

s <- ssa(f_n, L = 96)
r <- reconstruct(s, groups=list(
  trend = 1,
  sesonal = 2:3
))


print("Ошибки при SSA")
[1] "Ошибки при SSA"
print(paste("Ошибка при вычислении C = 1: ", mse(f_C, r$trend) |> format(scientific = TRUE, digits = 2)  ))
[1] "Ошибка при вычислении C = 1:  9.6e-05"
print(paste("Ошибка при вычислении cos(pi/12): ", mse(f_c, r$sesonal) |> format(scientific = TRUE, digits = 2)))
[1] "Ошибка при вычислении cos(pi/12):  9.6e-05"
lines(1:n, r$trend)
lines(1:n, r$sesonal)

Проверка разделимости непериодических компонент + автогруппировка SSA

n <- 96*2-1
L <- 96
eps <- 1/97

C <- 1
omega_cs <- 1/12
omega_sn <- 1/24
a <- 1/100
f_sum <- function(x){
  f_const(x, C = C) +
    f_cos(x, omega = omega_cs) +
    f_exp(x, a = a) +
    f_sin(x, omega = omega_sn)
}


f_C <- f_const |> generate_ts(n, C = C)
f_c <- f_cos |> generate_ts(n, omega = omega_cs)
f_s <- f_sin |> generate_ts(n, omega = omega_sn)
f_e <- f_exp |> generate_ts(n, a = a)

f_n <- f_sum(1:n)

library(xtable)
Предупреждение: пакет ‘xtable’ был собран под R версии 4.2.3
# Шаг 2: Создание примера данных
data <- data.frame(
  Метод = c("SSA", "CiSSA"),
  e_err = c(20, 20),
  c_err = c(23, 35),
  ec_err = c(20, 20),
  sin_err = c (20, 20),
  cos_err = c(1, 1)
)


# Отрисовка ряда f_n
plot(f_n, type = "l", lwd = 3, col = 'red', ylim = c(-2, 10),
     xlab = "Время", ylab = "Значения ряда", main = "Разложение временного ряда")

# Добавление отдельных компонентов (f_C, f_c, f_e)
lines(f_C, col = "blue")  # Компонент f_C
lines(f_c, col = "blue")  # Компонент f_c
lines(f_e, col = "blue")  # Компонент f_e
lines(f_s, col = "blue")

# Легенда
legend("topleft", legend = c("Весь ряд", "Компоненты"), 
       col = c("red", "blue"), lty = 1, lwd = 3)









c <- circulant_SSA(f_n, L = L, extend_flag = TRUE)
# r <- c$t_series
r <- grouping_cissa(c,
                    groups = list(
                      # trend = c(0, 1/100),
                      trend = c(-1, 1/25),
                      sesonal_cos = c(1/12-eps, 1/12+eps),
                      sesonal_sin = c(1/24 - eps, 1/24+eps)
                    ))$t_series

data$cos_err[2] <- mse(f_s, r$sesonal_sin) |> formatC(format = "e", digits = 1)
data$sin_err[2] <- mse(f_c, r$sesonal_cos) |> formatC(format = "e", digits = 1)
data$ec_err[2] <- mse(f_C+f_e, r$trend) |> formatC(format = "e", digits = 1)


# png("C:/Users/nik1m/Desktop/уник/6 сем/курсач/Текст работы/img/trend inseparability/CiSSA.png")  # сохранение в формате PNG

plot(1:n, f_n, type = "l", lwd=3, ylim= c(-2, 10), col="red",
     xlab = "Время", ylab = "Значения ряда", main = "CiSSA разложение временного ряда")
lines(1:n, r$trend, col = "blue")
lines(1:n, r$sesonal_sin, col = "blue")
lines(1:n, r$sesonal_cos, col = "blue")

# Легенда
legend("topleft", legend = c("Весь ряд", "Компоненты"), 
       col = c("red", "blue"), lty = 1, lwd = 3)


# dev.off()  # завершение сохранения










s <- ssa(f_n, L)
#e <- eossa_new(s, nested.groups = list(1:10), clust_type = "distance", k= 7)
e <- eossa(s, 1:10, k = 7)

g_sesonal <- grouping.auto(e, base = "eigen",
                   freq.bins = list(trend = c(2*eps),
                                    sesonal2 = c(1/24-eps, 1/24+eps),
                                    sesonal1 = c(1/12-eps, 1/12+eps)
                                    ),
                   threshold = 0.1)


r <- Rssa::reconstruct(e, groups=c(list(exp = 1,
                                C = 2
                                ),
                             g_sesonal)
                 )

plot(wcor(e, groups = 1:24), scales = list(at = c(10, 20, 30)))
Предупреждение в wcor.ossa(e, groups = 1:24) :
  Component matrices are not F-orthogonal (max F-cor is 0.93). W-cor matrix can be irrelevant

data$c_err[1] <- mse(f_C, r$C) |> formatC(format = "e", digits = 1)
data$e_err[1] <- mse(f_e, r$exp) |> formatC(format = "e", digits = 1)
data$cos_err[1] <- mse(f_c, r$sesonal1) |> formatC(format = "e", digits = 1)
data$sin_err[1] <- mse(f_s, r$sesonal2) |> formatC(format = "e", digits = 1)
data$ec_err[1] <- mse(f_C+f_e, r$C+r$exp) |> formatC(format = "e", digits = 1)


# png("C:/Users/nik1m/Desktop/уник/6 сем/курсач/Текст работы/img/trend inseparability/SSA.png")  # сохранение в формате PNG

plot(1:n, f_n, type = "l", lwd=3, ylim= c(-2, 10), col="red",
     xlab = "Время", ylab = "Значения ряда", main = "SSA разложение временного ряда")

lines(1:n, r$trend, type = "l", col="green")
lines(1:n, r$exp, type = "l", ylim= c(-2, 10), col="blue")
lines(1:n, r$C, col = "blue")
lines(1:n, r$sesonal1, col = "blue")
lines(1:n, r$sesonal2, col = "blue")

# Легенда
legend("topleft", legend = c("Весь ряд", "Компоненты"), 
       col = c("red", "blue"), lty = 1, lwd = 3)








# Шаг 3: Преобразование данных в формат LaTeX
table_latex <- xtable(data, caption = "Example Table")

# Шаг 4: Вывод таблицы в LaTeX файл
print(table_latex, include.rownames = FALSE)
% latex table generated in R 4.2.2 by xtable 1.8-4 package
% Tue Mar  4 20:43:26 2025
\begin{table}[ht]
\centering
\begin{tabular}{llllll}
  \hline
Метод & e\_err & c\_err & ec\_err & sin\_err & cos\_err \\ 
  \hline
SSA & 2.2e-25 & 2.2e-25 & 4.2e-28 & 3.8e-29 & 1.6e-29 \\ 
  CiSSA & 20 & 35 & 1.4e-03 & 7.7e-04 & 1.9e-03 \\ 
   \hline
\end{tabular}
\caption{Example Table} 
\end{table}

Пример cos*exp

n <- 96*2-1
L <- 96
eps <- 1/(L+1)

C <- 1
omega_cs <- 1/12
omega_sn <- 1/24
a <- 1/100
omega_exp <- 1/48
f_sum <- function(x){
    f_cos(x, omega = omega_cs) +
    f_exp_mod_harm_series(x, a = a, omega = omega_exp) +
    f_sin(x, omega = omega_sn) 
}


f_c <- f_cos |> generate_ts(n, omega = omega_cs)
f_s <- f_sin |> generate_ts(n, omega = omega_sn)
f_e <- f_exp_mod_harm_series |> generate_ts(n, a = a, omega = omega_exp)

f_n <- f_sum(1:n)

library(xtable)

# Шаг 2: Создание примера данных
data <- data.frame(
  Метод = c("SSA", "CiSSA"),
  exp_err = c(20, 20),
  sin_err = c (20, 20),
  cos_err = c(1, 1)
)


# Отрисовка ряда f_n
plot(f_n, type = "l", lwd = 3, col = 'red', ylim = c(-10, 10),
     xlab = "Время", ylab = "Значения ряда", main = "Разложение временного ряда")

# Добавление отдельных компонентов (f_C, f_c, f_e)
lines(f_c, col = "blue")  # Компонент f_c
lines(f_e, col = "blue")  # Компонент f_e
lines(f_s, col = "blue")

# Легенда
legend("topleft", legend = c("Весь ряд", "Компоненты"), 
       col = c("red", "blue"), lty = 1, lwd = 3)









c <- circulant_SSA(f_n, L = L, extend_flag = TRUE)
# r <- c$t_series
r <- grouping_cissa(c,
                    groups = list(
                      trend = c(0, 1/26-eps),
                      sesonal_cos = c(1/12-eps, 1/12+eps),
                      sesonal_sin = c(1/24-eps, 1/24+eps)
                    ))$t_series

data$cos_err[2] <- mse(f_s, r$sesonal_sin) |> formatC(format = "e", digits = 1)
data$sin_err[2] <- mse(f_c, r$sesonal_cos) |> formatC(format = "e", digits = 1)
data$exp_err[2] <- mse(f_e, r$trend) |> formatC(format = "e", digits = 1)


# png("C:/Users/nik1m/Desktop/уник/6 сем/курсач/Текст работы/img/trend inseparability/CiSSA.png")  # сохранение в формате PNG

plot(1:n, f_n, type = "l", lwd=3, ylim= c(-10, 10), col="red",
     xlab = "Время", ylab = "Значения ряда", main = "CiSSA разложение временного ряда")
lines(1:n, r$trend, col = "blue")
lines(1:n, r$sesonal_sin, col = "blue")
lines(1:n, r$sesonal_cos, col = "blue")

# Легенда
legend("topleft", legend = c("Весь ряд", "Компоненты"), 
       col = c("red", "blue"), lty = 1, lwd = 3)


# dev.off()  # завершение сохранения










s <- ssa(f_n, L)
e <- eossa_new(s, nested.groups = list(1:30), clust_type = "distance")

g_sesonal <- grouping.auto(e, base = "eigen",
                   freq.bins = list(trend = c(1/25-eps),
                                    sesonal2 = c(1/24-eps, 1/24+eps),
                                    sesonal1 = c(1/12-eps, 1/12+eps)
                                    ),
                   threshold = 0.1)


r <- reconstruct(e, groups= g_sesonal)

plot(wcor(e, groups = 1:24), scales = list(at = c(10, 20, 30)))
Предупреждение в wcor.ossa(e, groups = 1:24) :
  Component matrices are not F-orthogonal (max F-cor is -0.529). W-cor matrix can be irrelevant

data$exp_err[1] <- mse(f_e, r$trend)  |> formatC(format = "e", digits = 1)
data$cos_err[1] <- mse(f_c, r$sesonal1) |> formatC(format = "e", digits = 1)
data$sin_err[1] <- mse(f_s, r$sesonal2) |> formatC(format = "e", digits = 1)


# png("C:/Users/nik1m/Desktop/уник/6 сем/курсач/Текст работы/img/trend inseparability/SSA.png")  # сохранение в формате PNG

plot(1:n, f_n, type = "l", lwd=3, ylim= c(-10, 10), col="red",
     xlab = "Время", ylab = "Значения ряда", main = "SSA разложение временного ряда")

lines(1:n, r$trend, type = "l", col="blue")
lines(1:n, r$sesonal1, col = "blue")
lines(1:n, r$sesonal2, col = "blue")

# Легенда
legend("topleft", legend = c("Весь ряд", "Компоненты"), 
       col = c("red", "blue"), lty = 1, lwd = 3)








# Шаг 3: Преобразование данных в формат LaTeX
table_latex <- xtable(data, caption = "Example Table")

# Шаг 4: Вывод таблицы в LaTeX файл
print(table_latex, include.rownames = FALSE)
% latex table generated in R 4.2.2 by xtable 1.8-4 package
% Tue Mar  4 20:43:28 2025
\begin{table}[ht]
\centering
\begin{tabular}{llll}
  \hline
Метод & exp\_err & sin\_err & cos\_err \\ 
  \hline
SSA & 4.7e-29 & 1.1e-29 & 8.4e-30 \\ 
  CiSSA & 3.2e-02 & 1.0e-03 & 5.8e-03 \\ 
   \hline
\end{tabular}
\caption{Example Table} 
\end{table}

Данные IP

library(readxl)
Предупреждение: пакет ‘readxl’ был собран под R версии 4.2.3
data <- read_excel("Data/International_Financial_Statistics_.xlsx")
New names:
• `` -> `...2`
• `` -> `...3`
• `` -> `...4`
• `` -> `...5`
• `` -> `...6`
• `` -> `...7`
• `` -> `...8`
• `` -> `...9`
• `` -> `...10`
• `` -> `...11`
• `` -> `...12`
• `` -> `...13`
• `` -> `...14`
• `` -> `...15`
• `` -> `...16`
• `` -> `...17`
• `` -> `...18`
• `` -> `...19`
• `` -> `...20`
• `` -> `...21`
• `` -> `...22`
• `` -> `...23`
• `` -> `...24`
• `` -> `...25`
• `` -> `...26`
• `` -> `...27`
• `` -> `...28`
• `` -> `...29`
• `` -> `...30`
• `` -> `...31`
• `` -> `...32`
• `` -> `...33`
• `` -> `...34`
• `` -> `...35`
• `` -> `...36`
• `` -> `...37`
• `` -> `...38`
• `` -> `...39`
• `` -> `...40`
• `` -> `...41`
• `` -> `...42`
• `` -> `...43`
• `` -> `...44`
• `` -> `...45`
• `` -> `...46`
• `` -> `...47`
• `` -> `...48`
• `` -> `...49`
• `` -> `...50`
• `` -> `...51`
• `` -> `...52`
• `` -> `...53`
• `` -> `...54`
• `` -> `...55`
• `` -> `...56`
• `` -> `...57`
• `` -> `...58`
• `` -> `...59`
• `` -> `...60`
• `` -> `...61`
• `` -> `...62`
• `` -> `...63`
• `` -> `...64`
• `` -> `...65`
• `` -> `...66`
• `` -> `...67`
• `` -> `...68`
• `` -> `...69`
• `` -> `...70`
• `` -> `...71`
• `` -> `...72`
• `` -> `...73`
• `` -> `...74`
• `` -> `...75`
• `` -> `...76`
• `` -> `...77`
• `` -> `...78`
• `` -> `...79`
• `` -> `...80`
• `` -> `...81`
• `` -> `...82`
• `` -> `...83`
• `` -> `...84`
• `` -> `...85`
• `` -> `...86`
• `` -> `...87`
• `` -> `...88`
• `` -> `...89`
• `` -> `...90`
• `` -> `...91`
• `` -> `...92`
• `` -> `...93`
• `` -> `...94`
• `` -> `...95`
• `` -> `...96`
• `` -> `...97`
• `` -> `...98`
• `` -> `...99`
• `` -> `...100`
• `` -> `...101`
• `` -> `...102`
• `` -> `...103`
• `` -> `...104`
• `` -> `...105`
• `` -> `...106`
• `` -> `...107`
• `` -> `...108`
• `` -> `...109`
• `` -> `...110`
• `` -> `...111`
• `` -> `...112`
• `` -> `...113`
• `` -> `...114`
• `` -> `...115`
• `` -> `...116`
• `` -> `...117`
• `` -> `...118`
• `` -> `...119`
• `` -> `...120`
• `` -> `...121`
• `` -> `...122`
• `` -> `...123`
• `` -> `...124`
• `` -> `...125`
• `` -> `...126`
• `` -> `...127`
• `` -> `...128`
• `` -> `...129`
• `` -> `...130`
• `` -> `...131`
• `` -> `...132`
• `` -> `...133`
• `` -> `...134`
• `` -> `...135`
• `` -> `...136`
• `` -> `...137`
• `` -> `...138`
• `` -> `...139`
• `` -> `...140`
• `` -> `...141`
• `` -> `...142`
• `` -> `...143`
• `` -> `...144`
• `` -> `...145`
• `` -> `...146`
• `` -> `...147`
• `` -> `...148`
• `` -> `...149`
• `` -> `...150`
• `` -> `...151`
• `` -> `...152`
• `` -> `...153`
• `` -> `...154`
• `` -> `...155`
• `` -> `...156`
• `` -> `...157`
• `` -> `...158`
• `` -> `...159`
• `` -> `...160`
• `` -> `...161`
• `` -> `...162`
• `` -> `...163`
• `` -> `...164`
• `` -> `...165`
• `` -> `...166`
• `` -> `...167`
• `` -> `...168`
• `` -> `...169`
• `` -> `...170`
• `` -> `...171`
• `` -> `...172`
• `` -> `...173`
• `` -> `...174`
• `` -> `...175`
• `` -> `...176`
• `` -> `...177`
• `` -> `...178`
• `` -> `...179`
• `` -> `...180`
• `` -> `...181`
• `` -> `...182`
• `` -> `...183`
• `` -> `...184`
• `` -> `...185`
• `` -> `...186`
• `` -> `...187`
• `` -> `...188`
• `` -> `...189`
• `` -> `...190`
• `` -> `...191`
• `` -> `...192`
• `` -> `...193`
• `` -> `...194`
• `` -> `...195`
• `` -> `...196`
• `` -> `...197`
• `` -> `...198`
• `` -> `...199`
• `` -> `...200`
• `` -> `...201`
• `` -> `...202`
• `` -> `...203`
• `` -> `...204`
• `` -> `...205`
• `` -> `...206`
• `` -> `...207`
• `` -> `...208`
• `` -> `...209`
• `` -> `...210`
• `` -> `...211`
• `` -> `...212`
• `` -> `...213`
• `` -> `...214`
• `` -> `...215`
• `` -> `...216`
• `` -> `...217`
• `` -> `...218`
• `` -> `...219`
• `` -> `...220`
• `` -> `...221`
• `` -> `...222`
• `` -> `...223`
• `` -> `...224`
• `` -> `...225`
• `` -> `...226`
• `` -> `...227`
• `` -> `...228`
• `` -> `...229`
• `` -> `...230`
• `` -> `...231`
• `` -> `...232`
• `` -> `...233`
• `` -> `...234`
• `` -> `...235`
• `` -> `...236`
• `` -> `...237`
• `` -> `...238`
• `` -> `...239`
• `` -> `...240`
• `` -> `...241`
• `` -> `...242`
• `` -> `...243`
• `` -> `...244`
• `` -> `...245`
• `` -> `...246`
• `` -> `...247`
• `` -> `...248`
• `` -> `...249`
• `` -> `...250`
• `` -> `...251`
• `` -> `...252`
• `` -> `...253`
• `` -> `...254`
• `` -> `...255`
• `` -> `...256`
• `` -> `...257`
• `` -> `...258`
• `` -> `...259`
• `` -> `...260`
• `` -> `...261`
• `` -> `...262`
• `` -> `...263`
• `` -> `...264`
• `` -> `...265`
• `` -> `...266`
• `` -> `...267`
• `` -> `...268`
• `` -> `...269`
• `` -> `...270`
• `` -> `...271`
• `` -> `...272`
• `` -> `...273`
• `` -> `...274`
• `` -> `...275`
• `` -> `...276`
• `` -> `...277`
• `` -> `...278`
• `` -> `...279`
• `` -> `...280`
• `` -> `...281`
• `` -> `...282`
• `` -> `...283`
• `` -> `...284`
• `` -> `...285`
• `` -> `...286`
• `` -> `...287`
• `` -> `...288`
• `` -> `...289`
• `` -> `...290`
• `` -> `...291`
• `` -> `...292`
• `` -> `...293`
• `` -> `...294`
• `` -> `...295`
• `` -> `...296`
• `` -> `...297`
• `` -> `...298`
• `` -> `...299`
• `` -> `...300`
• `` -> `...301`
• `` -> `...302`
• `` -> `...303`
• `` -> `...304`
• `` -> `...305`
• `` -> `...306`
• `` -> `...307`
• `` -> `...308`
• `` -> `...309`
• `` -> `...310`
• `` -> `...311`
• `` -> `...312`
• `` -> `...313`
• `` -> `...314`
• `` -> `...315`
• `` -> `...316`
• `` -> `...317`
• `` -> `...318`
• `` -> `...319`
• `` -> `...320`
• `` -> `...321`
• `` -> `...322`
• `` -> `...323`
• `` -> `...324`
• `` -> `...325`
• `` -> `...326`
• `` -> `...327`
• `` -> `...328`
• `` -> `...329`
• `` -> `...330`
• `` -> `...331`
• `` -> `...332`
• `` -> `...333`
• `` -> `...334`
• `` -> `...335`
• `` -> `...336`
• `` -> `...337`
• `` -> `...338`
• `` -> `...339`
• `` -> `...340`
• `` -> `...341`
• `` -> `...342`
• `` -> `...343`
• `` -> `...344`
• `` -> `...345`
• `` -> `...346`
• `` -> `...347`
• `` -> `...348`
• `` -> `...349`
• `` -> `...350`
• `` -> `...351`
• `` -> `...352`
• `` -> `...353`
• `` -> `...354`
• `` -> `...355`
• `` -> `...356`
• `` -> `...357`
• `` -> `...358`
• `` -> `...359`
• `` -> `...360`
• `` -> `...361`
• `` -> `...362`
• `` -> `...363`
• `` -> `...364`
• `` -> `...365`
• `` -> `...366`
• `` -> `...367`
• `` -> `...368`
• `` -> `...369`
• `` -> `...370`
• `` -> `...371`
• `` -> `...372`
• `` -> `...373`
• `` -> `...374`
• `` -> `...375`
• `` -> `...376`
• `` -> `...377`
• `` -> `...378`
• `` -> `...379`
• `` -> `...380`
• `` -> `...381`
• `` -> `...382`
• `` -> `...383`
• `` -> `...384`
• `` -> `...385`
• `` -> `...386`
• `` -> `...387`
• `` -> `...388`
• `` -> `...389`
• `` -> `...390`
• `` -> `...391`
• `` -> `...392`
• `` -> `...393`
• `` -> `...394`
• `` -> `...395`
• `` -> `...396`
• `` -> `...397`
• `` -> `...398`
• `` -> `...399`
• `` -> `...400`
• `` -> `...401`
• `` -> `...402`
• `` -> `...403`
• `` -> `...404`
• `` -> `...405`
• `` -> `...406`
• `` -> `...407`
• `` -> `...408`
• `` -> `...409`
• `` -> `...410`
• `` -> `...411`
• `` -> `...412`
• `` -> `...413`
• `` -> `...414`
• `` -> `...415`
• `` -> `...416`
• `` -> `...417`
• `` -> `...418`
• `` -> `...419`
• `` -> `...420`
• `` -> `...421`
• `` -> `...422`
• `` -> `...423`
• `` -> `...424`
• `` -> `...425`
• `` -> `...426`
• `` -> `...427`
• `` -> `...428`
• `` -> `...429`
• `` -> `...430`
• `` -> `...431`
• `` -> `...432`
• `` -> `...433`
• `` -> `...434`
• `` -> `...435`
• `` -> `...436`
• `` -> `...437`
• `` -> `...438`
• `` -> `...439`
• `` -> `...440`
• `` -> `...441`
• `` -> `...442`
• `` -> `...443`
• `` -> `...444`
• `` -> `...445`
• `` -> `...446`
• `` -> `...447`
• `` -> `...448`
• `` -> `...449`
• `` -> `...450`
• `` -> `...451`
• `` -> `...452`
• `` -> `...453`
• `` -> `...454`
• `` -> `...455`
• `` -> `...456`
• `` -> `...457`
• `` -> `...458`
• `` -> `...459`
• `` -> `...460`
• `` -> `...461`
• `` -> `...462`
• `` -> `...463`
• `` -> `...464`
• `` -> `...465`
• `` -> `...466`
• `` -> `...467`
• `` -> `...468`
• `` -> `...469`
• `` -> `...470`
• `` -> `...471`
• `` -> `...472`
• `` -> `...473`
• `` -> `...474`
• `` -> `...475`
• `` -> `...476`
• `` -> `...477`
• `` -> `...478`
• `` -> `...479`
• `` -> `...480`
• `` -> `...481`
• `` -> `...482`
• `` -> `...483`
• `` -> `...484`
• `` -> `...485`
• `` -> `...486`
• `` -> `...487`
• `` -> `...488`
• `` -> `...489`
• `` -> `...490`
• `` -> `...491`
• `` -> `...492`
• `` -> `...493`
• `` -> `...494`
• `` -> `...495`
• `` -> `...496`
• `` -> `...497`
• `` -> `...498`
• `` -> `...499`
• `` -> `...500`
• `` -> `...501`
• `` -> `...502`
• `` -> `...503`
• `` -> `...504`
• `` -> `...505`
• `` -> `...506`
• `` -> `...507`
• `` -> `...508`
• `` -> `...509`
• `` -> `...510`
• `` -> `...511`
• `` -> `...512`
• `` -> `...513`
• `` -> `...514`
• `` -> `...515`
• `` -> `...516`
• `` -> `...517`
• `` -> `...518`
• `` -> `...519`
• `` -> `...520`
• `` -> `...521`
• `` -> `...522`
• `` -> `...523`
• `` -> `...524`
• `` -> `...525`
• `` -> `...526`
• `` -> `...527`
• `` -> `...528`
• `` -> `...529`
• `` -> `...530`
• `` -> `...531`
• `` -> `...532`
• `` -> `...533`
• `` -> `...534`
• `` -> `...535`
• `` -> `...536`
• `` -> `...537`
• `` -> `...538`
• `` -> `...539`
• `` -> `...540`
• `` -> `...541`
• `` -> `...542`
• `` -> `...543`
• `` -> `...544`
• `` -> `...545`
• `` -> `...546`
• `` -> `...547`
• `` -> `...548`
• `` -> `...549`
• `` -> `...550`
• `` -> `...551`
• `` -> `...552`
• `` -> `...553`
• `` -> `...554`
• `` -> `...555`
• `` -> `...556`
• `` -> `...557`
• `` -> `...558`
• `` -> `...559`
• `` -> `...560`
• `` -> `...561`
• `` -> `...562`
• `` -> `...563`
• `` -> `...564`
• `` -> `...565`
• `` -> `...566`
• `` -> `...567`
• `` -> `...568`
• `` -> `...569`
• `` -> `...570`
• `` -> `...571`
• `` -> `...572`
• `` -> `...573`
• `` -> `...574`
• `` -> `...575`
• `` -> `...576`
• `` -> `...577`
• `` -> `...578`
• `` -> `...579`
data |> head()

Отрисовка данных IP

dates <- seq(as.Date("1970-01-01"), as.Date("2018-1-30"), by = "month")
IP_values <- data[2, -c(1, 2)] |> as.double() 
plot(dates, IP_values, type="l")

Cissa

Отрисовка трендовой составляющей чёрным цветом, основной временной ряд — красным

data_slice <- 1:537
dates_slice <- dates[data_slice]
IP_values_slice <- IP_values[data_slice]
eps <- 1/193

c <- circulant_SSA(IP_values_slice, L = 192, extend_flag = TRUE)
r <- c$t_series
r <- grouping_cissa(c,
                    groups = list(
                      trend = c(0, 1/192),
                      cycle = c(1/97, 5/95),
                      sesonal = c(1/13, 1/2+0.0001)
                    )
                    )$t_series
r_sesonal <-  grouping_cissa(c,
                             groups = list(
                              s1 = c(16/192 - eps, 16/192 + eps),
                              s2 = c(32/192 - eps, 32/192 + eps),
                              s3 = c(48/192 - eps, 48/192 + eps),
                              s4 = c(64/192 - eps, 64/192 + eps),
                              s5 = c(80/192 - eps, 80/192 + eps),
                              s6 = c(96/192 - eps, 96/192 + eps)
                             )
                             )$t_series
# cissa_trend <- r[,1] + r[,2]
# cissa_cycle <- r[, 3:11] |> rowSums()
# cissa_sesonal <- r[, c(17, 33, 49, 65, 81, 97)] |> rowSums()
# cissa_residuals <- IP_values_slice - (cissa_trend + cissa_cycle + cissa_sesonal)

cissa_trend <- r$trend
cissa_cycle <- r$cycle
cissa_sesonal <- Reduce("+", r_sesonal |> within(rm(residuals)))
cissa_residuals <- IP_values_slice - (cissa_trend + cissa_cycle + cissa_sesonal)


plot(dates_slice, IP_values_slice,
     type="l", col = "black")
lines(dates_slice, cissa_trend,
      type="l", col = "red")


plot(dates_slice, cissa_cycle,
     type="l", col = "red")


plot(dates_slice, cissa_sesonal,
     type="l", col = "red")


plot(dates_slice, cissa_residuals,
     type="l", col = "red")


plot(dates_slice, IP_values_slice,
     type="l", col = "black")
lines(dates_slice, cissa_trend+cissa_cycle+cissa_sesonal,
      type="l", col = "red")

SSA fossa

s <- ssa(IP_values_slice, L = 192)
e <- fossa(s, 1:(11))
# e <- eossa_new(s, nested.groups = list(1:30), clust_type = "distance")
eps <- 1/193

groups <- grouping.auto(e,
                   freq.bins = list(trend = c(1/192),
                                    cycle = c(1/97, 5/95),
                                    s1 = c(16/192 - eps, 16/192 + eps),
                                    s2 = c(32/192 - eps, 32/192 + eps),
                                    s3 = c(48/192 - eps, 48/192 + eps),
                                    s4 = c(64/192 - eps, 64/192 + eps),
                                    s5 = c(80/192 - eps, 80/192 + eps),
                                    s6 = c(96/192 - eps, 96/192 + eps)
                                    ),
                   threshold = 0)


plot(wcor(e, groups = 1:30), scales = list(at = c(10, 20, 30)),
     main = "W-correlation matrix SSA (fossa)")


r <- reconstruct(e, groups=groups)

ssa_trend_f <- r$trend
ssa_cycle_f <- r$cycle
ssa_sesonal_f <- r$s1 + r$s2 + r$s3 + r$s4 + r$s5 + r$s6
ssa_residuals_f <- IP_values_slice - (ssa_trend_f + ssa_cycle_f + ssa_sesonal_f)

plot(dates_slice, IP_values_slice,
     type="l", col = "black")
lines(dates_slice, ssa_trend_f,
      type="l", col = "magenta")


plot(dates_slice, ssa_cycle_f, 
     type="l", col = "magenta")


plot(dates_slice, ssa_sesonal_f, 
     type="l", col = "magenta")


plot(dates_slice, ssa_residuals_f,
     type="l", col = "magenta")

SSA eossa

library(Rssa)
source("eossa_new.r")
s <- ssa(IP_values_slice, L = 192)
e <- eossa_new(s, nested.groups = list(1:20), clust_type = "distance")




groups <- grouping.auto(e,
                   freq.bins = list(trend = c(1/192),
                                    cycle = c(1/97, 5/95),
                                    s1 = c(16/192 - eps, 16/192 + eps),
                                    s2 = c(32/192 - eps, 32/192 + eps),
                                    s3 = c(48/192 - eps, 48/192 + eps),
                                    s4 = c(64/192 - eps, 64/192 + eps),
                                    s5 = c(80/192 - eps, 80/192 + eps),
                                    s6 = c(96/192 - eps, 96/192 + eps)
                                    ),
                   threshold = 0)
plot(wcor(e, groups = 1:30), scales = list(at = c(10, 20, 30)),
     main = "W-correlation matrix SSA (eossa)")
Предупреждение в wcor.ossa(e, groups = 1:30) :
  Component matrices are not F-orthogonal (max F-cor is 0.0564). W-cor matrix can be irrelevant

r <- reconstruct(e, groups=groups)

ssa_trend <- r$trend
ssa_cycle <- r$cycle
ssa_sesonal <- r$s1 + r$s2 + r$s3 + r$s4 + r$s5 + r$s6
ssa_residuals <- IP_values_slice - (ssa_trend + ssa_cycle + ssa_sesonal)

plot(dates_slice, IP_values_slice,
     type="l", col = "black")
lines(dates_slice, ssa_trend,
      type="l", col = "blue")


plot(dates_slice, ssa_cycle, 
     type="l", col = "blue")


plot(dates_slice, ssa_sesonal, 
     type="l", col = "blue")


plot(dates_slice, ssa_residuals,
     type="l", col = "blue")

plot(dates_slice, IP_values_slice,
     main = "IP USA тренд",xlab = "Время", ylab = "Значение",
     type="l", col = "black")
lines(dates_slice, ssa_trend,
      type="l", col = "blue", lwd=2)
lines(dates_slice, ssa_trend_f,
      type="l", col = "magenta", lwd=2)
lines(dates_slice, cissa_trend,
      type="l", col = "red", lwd=2)
# Легенда
legend("topleft", legend = c("Весь ряд", "CiSSA тренд", "SSA тренд (eossa)", "SSA тренд (fossa)"), 
       col = c("black", "red", "blue", "magenta"), lty = 1, lwd = 3)



plot(dates_slice, ssa_cycle,
     main = "IP USA цикличность", xlab = "Время", ylab = "Значение",
     type="l", col = "blue", ylim=c(-10, 10), lwd=2)
lines(dates_slice, cissa_cycle,
      type="l", col = "red", lwd=2)
lines(dates_slice, ssa_cycle_f,
      type="l", col = "magenta", lwd=2)
# Легенда
legend("topleft", legend = c("CiSSA", "SSA (eossa)", "SSA (fossa)"), 
       col = c("red", "blue", "magenta"), lty = 1, lwd = 3)



plot(dates_slice, IP_values_slice,
     main = "IP USA тренд + цикличность",xlab = "Время", ylab = "Значение",
     type="l", col = "black")
lines(dates_slice, ssa_trend + ssa_cycle,
      type="l", col = "blue", lwd=2)
lines(dates_slice, ssa_trend_f + ssa_cycle_f,
      type="l", col = "magenta", lwd=2)
lines(dates_slice, cissa_trend + cissa_cycle,
      type="l", col = "red", lwd=2)
# Легенда
legend("topleft", legend = c("Весь ряд", "CiSSA", "SSA (eossa)", "SSA (fossa)"), 
       col = c("black", "red", "blue", "magenta"), lty = 1, lwd = 3)

NA
NA
# Настройка графиков для отображения двух графиков один под другим с общей осью X
layout(matrix(c(1, 2), nrow = 2, byrow = TRUE), heights = c(1, 1.2))

# Построение первого графика
par(mar = c(2, 4, 2, 2)) # Уменьшение нижнего отступа
plot(dates_slice, ssa_sesonal, type = "l", col = "blue", lwd = 1,
     main = "SSA (eossa) сезонность", xlab = "", ylab = "Значение")
# Добавление оси X внизу первого графика, но с пустыми метками
axis(1, labels = FALSE)

# Построение второго графика
par(mar = c(5, 4, 2, 2)) # Увеличение нижнего отступа
plot(dates_slice, ssa_sesonal_f, type = "l", col = "magenta", lwd = 1,
     main = "SSA (fossa) сезонность", xlab = "Время", ylab = "Значение")

par(mar = c(3, 4, 2, 2)) # Увеличение нижнего отступа

plot(dates_slice, cissa_sesonal, type = "l", col = "red", lwd = 1,
     main = "CiSSA сезонность", xlab = "Время", ylab = "Значение")

# Восстановление макета по умолчанию
layout(1)

NA
NA
plot(dates_slice, ssa_residuals, 
     main = "IP USA остаток", xlab = "Время", ylab = "Значение",
     type="l", col = "blue", ylim=c(-2, 2))
lines(dates_slice, cissa_residuals,
      type="l", col = "red")
lines(dates_slice, ssa_residuals_f,
      type="l", col = "magenta")
legend("topleft", legend = c("CiSSA", "SSA (eossa)", "SSA (fossa)"), 
       col = c("red", "blue", "magenta"), lty = 1, lwd = 3)

ssa_residuals |> density() |> plot()

cissa_residuals |> density() |> plot()

Отделение сигнала от шума

set.seed(100)

n_mse_tests <- function(n){
  n <- 96*2-1
  L <- 96
  sigma <- 0.1
  
  
  C <- 1
  omega_cs <- 1/12
  omega_sn <- 1/24
  a <- 1/100
  f_sum <- function(x){
    f_const(x, C = C) +
      f_cos(x, omega = omega_cs) +
      f_exp(x, a = a) +
      f_sin(x, omega = omega_sn)
  }
  
  
  f_C <- f_const |> generate_ts(n, C = C)
  f_c <- f_cos |> generate_ts(n, omega = omega_cs)
  f_s <- f_sin |> generate_ts(n, omega = omega_sn)
  f_e <- f_exp |> generate_ts(n, a = a)
  
  mse_lst <- list()
  for (i in 1:n) {
    f_noise <- rnorm(n, sd = sigma)
    
    f_n <- f_sum(1:n) + f_noise
    
    
    
    c <- circulant_SSA(f_n, L = L, extend_flag = TRUE)
    # r <- c$t_series
    r <- grouping_cissa(c, groups= list(trend = c(0, 1/1000), 
                                        sesonal2 = c(1/25, 1/23),
                                        sesonal1 = c(1/13, 1/10)
                                        ))$t_series
    
    # mse_lst$cissa <- c(mse_lst$cissa, mse(f_sum(1:n), r[, 9] + r[, 5] + r[, 1])) 
    mse_lst$cissa <- c(mse_lst$cissa,
                       mse(f_sum(1:n),
                           r$trend + r$sesonal1 + r$sesonal2)) 
    
    
    
    
    s <- ssa(f_n, L)
    # e <- eossa(s, 1:10, k = 6)
    e <- fossa(s)
    
    g_sesonal <- grouping.auto(e, base = "eigen",
                       freq.bins = list(trend = 1/1000, 
                                        sesonal2 = c(1/25, 1/23),
                                        sesonal1 = c(1/13, 1/10)
                                        ),
                       threshold = 0.5)
    
    r <- reconstruct(e, groups=c(list(exp = 1, C = 2), g_sesonal))
    
    mse_lst$ssa <- 
      c(mse_lst$ssa, mse(f_sum(1:n), r$trend + r$sesonal2 + r$sesonal1))
 
  }
  return(mse_lst)
}

res_mse_test <- n_mse_tests(100)
# Оценка плотности
density_estimate_cissa <- density(res_mse_test$cissa)

# Построение графика плотности
plot(density_estimate_cissa, main = "Оценка плотности", 
     xlab = "Значение", ylab = "Плотность", 
     col = "blue", lwd = 2)


density_estimate_ssa <- density(res_mse_test$ssa)

# Построение графика плотности
plot(density_estimate_ssa, main = "Оценка плотности", 
     xlab = "Значение", ylab = "Плотность", 
     col = "blue", lwd = 2)


res_mse_test$cissa |> summary()
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
0.02299 0.03062 0.03345 0.03378 0.03575 0.04800 
res_mse_test$cissa |> sd()
[1] 0.004333975
res_mse_test$ssa |> summary()
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
0.000576 0.001710 0.002125 0.002228 0.002585 0.006311 
res_mse_test$ssa |> sd()
[1] 0.0008283841

Как выполняется расширение ряда

IP_values_slice |> extend(192) |>
  plot(type="l", lwd = 3, ylab="Значения", xlab = "Индексы", main="Расширение временного ряда IP values")
lines((192:(length(IP_values_slice) + 192 -1)) + 1, IP_values_slice, type="l", col="red")

n <- 96*2 + 6
x <- 0:(n-1)
y <- sin(2*pi/12 * x)
L <- 96+6
plot(y |> extend(L), type="l", lwd = 4, ylab="Значения", xlab = "Индексы", main="Расширение временного ряда sin")
lines((x+L+1), y, type="l", col="red", lwd = 2)

CiSSA через Фурье

IP_values

cissa_like_fourier_transform <- function(ts, L){
  reconstruct_fft <- function(x, y, frequencies) {
    fft_y <- fft(y)
  
    amplitudes <- Mod(fft_y)
    phases <- Arg(fft_y)
    
    reconstructed <- matrix(0, length(amplitudes), length(x))
    n <- length(amplitudes)
    for (i in 1:(length(amplitudes))) {
      reconstructed[i, ] <-
        amplitudes[i] * 
        cos(2 * pi * frequencies[i] * (x) + phases[i]) /
        n
    }
    return(list(
      ts = reconstructed,
      frequencies = frequencies
      ))
  }
  
  n <- length(ts)
  x <- 0:(n-1)
  L <- L
  frequencies <- (0:(L-1)) / L
  y <- ts
  y_main <- y
  x_main <- x
  
  X <- hankel(y, L)
  K <- dim(X)[2]
  res <- list()
  for (i in 1:K){
    y <- X[, i]
    x <- x_main[1:(1 + L - 1)]
    res[[i]] <- reconstruct_fft(x, y, frequencies)$ts
  }
  
  # for (i in 1:L){
  #   plot(x, res[[i]][9, ])
  # }
  
  res_mult <- res
  # res
  
  averaging <- function(res_comp_wise_mult){
    K <- dim(X)[2]
    counters <- rep(0, n)
    res <- matrix(0, ncol = n, nrow = L)
    for (i in 1:length(res_comp_wise_mult)){
      res[, i:(i+L-1)] <- res[, i:(i+L-1)] + res_comp_wise_mult[[i]]
      counters[i:(i+L-1)] <- counters[i:(i+L-1)] + 1
    }
    for (i in 1:n){
      res[, i] <- res[, i] / counters[i]
    }
    res
  }
  
  avr <- averaging(res_mult)
  
  group_by_elementary_freq_foureir <- function(res_averaged){
    nf2 <- 0
    if (L %% 2) {
      nf2 <- (L + 1) / 2 - 1
    } else {
      nf2 <- L / 2 - 1
    }
    nft <- nf2 + abs((L %% 2) - 2)
    
    Z <- matrix(0, ncol = nft, nrow = n)
    
    # print(Z |> dim())
    # print(res_averaged |> dim())
    
    Z[, 1] <- res_averaged[1, ]
    for (k in 1:nf2) {
      Z[, k + 1] <- res_averaged[k + 1, ] + res_averaged[L + 2 - (k + 1), ]
    }
    if (L %% 2 != 0) {
      Z[, nft] <- res_averaged[nft, ]
    }
    
    
    return(list(
      t_series = Z,
      freq = (0:dim(Z)[2])/L
    ))
  }


  rs <- group_by_elementary_freq_foureir(avr)
  return(rs)
}
data_slice <- 1:537
dates_slice <- dates[data_slice]
IP_values_slice <- IP_values[data_slice]
eps <- 1/193


c <- circulant_SSA(IP_values_slice, L = 192, extend_flag = FALSE)
r <- c$t_series

c_ft <- cissa_like_fourier_transform(IP_values_slice, L = 192)
r_ft <- c_ft$t_series

for (i in 1:dim(r)[2]){
  plot(data_slice, r_ft[, i], col= "red", type = "l", lwd = 2)
  lines(data_slice, r[, i])
}

Сравнение разложений всего временного ряда через метод Фурье, SSA, auto_SSA, CiSSA и CiSSA с расширением ряда

reconstruct_fft <- function(x_init, y_init, extend_flag = FALSE) {
    x <- x_init
    y <- y_init
    N <- length(y_init)
    H <- 0
    if (extend_flag == TRUE){
      H <- length(y) %/% 2
      y <- extend(y, H)
      x <- 0:(length(y) - 1)
    }
    
    frequencies <- (0:(length(x)-1)) / length(x)
    fft_y <- fft(y)
    
    amplitudes <- Mod(fft_y)
    phases <- Arg(fft_y)
    
    reconstructed <- matrix(0, length(amplitudes), length(x))
    n <- length(amplitudes)
    L <- n
    for (i in 1:(length(amplitudes))) {
      reconstructed[i, ] <-
        amplitudes[i] * 
        cos(2 * pi * frequencies[i] * (x) + phases[i]) /
        n
    }
    
    
    
  
    group_by_elementary_freq_foureir <- function(res_averaged){
      nf2 <- 0
      if (L %% 2) {
        nf2 <- (L + 1) / 2 - 1
      } else {
        nf2 <- L / 2 - 1
      }
      nft <- nf2 + abs((L %% 2) - 2)
      
      Z <- matrix(0, ncol = nft, nrow = n)
      
      # print(Z |> dim())
      # print(res_averaged |> dim())
      
      Z[, 1] <- res_averaged[1, ]
      for (k in 1:nf2) {
        Z[, k + 1] <- res_averaged[k + 1, ] + res_averaged[L + 2 - (k + 1), ]
      }
      if (L %% 2 != 0) {
        Z[, nft] <- res_averaged[nft, ]
      }
      
      
      return(list(
        t_series = Z[(H+1):(N+H), ],
        freq = (0:(dim(Z)[2]-1))/L
      ))
    }
  
  
    rs <- group_by_elementary_freq_foureir(reconstructed)
    
    
    return(list(
      t_series = rs$t_series,
      freq = rs$freq
      ))
  }

Идеальный случай для CiSSA и Fourier

n <- 96*2
L <- 96
x <- 0:(n-1)
y1 <- sin(2*pi/12 * x)
y2 <- cos(2*pi/3 * x)/2
y <- y1 + y2
X <- hankel(y, L = L)
eps <- 1/(n+1)

s_ssa <- ssa(y[1:(n-1)], L)
r_ssa <- reconstruct(s_ssa, groups = list(
  F1 = c(1, 2),
  F2 = c(3, 4)
))
# r_ssa <- reconstruct(s_ssa, groups=list(
#   sesonal_sin = c(1, 2),
#   sesonal_cos = c(3, 4)
# ))
# plot(x, r_ssa$F1, type="l")
# plot(x, r_ssa$F2, type= "l")
# plot(wcor(s_ssa, groups = 1:10), scales = list(at = c(10, 20, 30)))
e_ssa <- eossa_new(s_ssa, nested.groups = list(1:4), clust_type = "distance")
g_sesonal_e <- grouping.auto(e_ssa, base = "eigen",
                       freq.bins = list(
                         sesonal_sin = c(1/12-eps, 1/12+eps),
                         sesonal_cos = c(1/3-eps, 1/3+eps)
                                        ),
                       threshold = 0.5)
r_ssa_e <- reconstruct(e_ssa, groups=g_sesonal_e)
# plot(x, r_ssa_e$sesonal_sin)
# plot(x, r_ssa_e$sesonal_cos)



r_fft <- reconstruct_fft(x, y)
r_fft_grouped <- grouping_cissa(r_fft,
                    groups = list(
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series

r_fft_extended <- reconstruct_fft(x, y, TRUE)
r_fft_grouped_extended <- grouping_cissa(r_fft_extended,
                    groups = list(
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series

# r_fft_grouped$sesonal_sin |> length()

# plot(x, r_fft_grouped$sesonal_sin)
# plot(x, r_fft_grouped$sesonal_cos)
# plot(x, r_fft_grouped$residuals)


r_cissa <- circulant_SSA(y, L)
r_cissa_grouped <- grouping_cissa(r_cissa,
                    groups = list(
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series


r_cissa_ext <- circulant_SSA(y, L, extend_flag = TRUE)
r_cissa_grouped_ext <- grouping_cissa(r_cissa_ext,
                    groups = list(
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series

# plot(x, r_cissa_grouped$sesonal_sin)
# plot(x, r_cissa_grouped$sesonal_cos)
# plot(x, r_cissa_grouped$residuals)

library(xtable)

# Шаг 2: Создание примера данных
data <- data.frame(
  Метод = c("SSA", "SSA EOSSA","Fourier", "CiSSA", "CiSSA extended", "Fourier extended"),
  sin_err = c (1, 20, 20, 1, 1, 1),
  cos_err = c(1, 1, 1, 1, 1, 1),
  all_err = c(1, 1, 1, 1, 1, 1)
)

data$sin_err[1] <- mse(y1[1:(n-1)], r_ssa$F1) |>
  formatC(format = "e", digits = 1) 
data$cos_err[1] <- mse(y2[1:(n-1)], r_ssa$F2) |>
  formatC(format = "e", digits = 1)
data$all_err[1] <- mse(y1[1:(n-1)] + y2[1:(n-1)], r_ssa$F1 + r_ssa$F2) |>
  formatC(format = "e", digits = 1)

data$cos_err[2] <- mse(y1[1:(n-1)], r_ssa_e$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[2] <- mse(y2[1:(n-1)], r_ssa_e$sesonal_cos) |>
  formatC(format = "e", digits = 1)
data$all_err[2] <- mse(y1[1:(n-1)] + y2[1:(n-1)],
                       r_ssa_e$sesonal_sin + r_ssa_e$sesonal_cos) |>
  formatC(format = "e", digits = 1)


data$cos_err[3] <- mse(y1, r_fft_grouped$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[3] <- mse(y2, r_fft_grouped$sesonal_cos) |>
  formatC(format = "e", digits = 1)
data$all_err[3] <- mse(y1 + y2,
                       r_fft_grouped$sesonal_sin + r_fft_grouped$sesonal_cos
                       ) |>
  formatC(format = "e", digits = 1)


data$cos_err[4] <- mse(y1, r_cissa_grouped$sesonal_sin) |> 
  formatC(format = "e", digits = 1)
data$sin_err[4] <- mse(y2, r_cissa_grouped$sesonal_cos) |> 
  formatC(format = "e", digits = 1)
data$all_err[4] <- mse(y1 + y2,
                       r_cissa_grouped$sesonal_sin + r_cissa_grouped$sesonal_cos
                       ) |>
  formatC(format = "e", digits = 1)


data$cos_err[5] <- mse(y1, r_cissa_grouped_ext$sesonal_sin) |> 
  formatC(format = "e", digits = 1)
data$sin_err[5] <- mse(y2, r_cissa_grouped_ext$sesonal_cos) |> 
  formatC(format = "e", digits = 1)
data$all_err[5] <- mse(y1 + y2,
                       r_cissa_grouped_ext$sesonal_sin + r_cissa_grouped_ext$sesonal_cos
                       ) |>
  formatC(format = "e", digits = 1)


data$cos_err[6] <- mse(y1, r_fft_grouped_extended$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[6] <- mse(y2, r_fft_grouped_extended$sesonal_cos) |>
  formatC(format = "e", digits = 1)
data$all_err[6] <- mse(y1 + y2,
                       r_fft_grouped_extended$sesonal_sin + r_fft_grouped_extended$sesonal_cos
                       ) |>
  formatC(format = "e", digits = 1)


table_latex <- xtable(data, caption = "Example Table")

# Шаг 4: Вывод таблицы в LaTeX файл
print(table_latex, include.rownames = FALSE)

Идеальный случай с шумом


data <- list(
  Метод = c("SSA","SSA EOSSA","Fourier", "CiSSA", "CiSSA extended", "Fourier extended"),
  sin_err = list(list(), list(), list(), list(), list(), list()),
  cos_err = list(list(), list(), list(), list(), list(), list()),
  all_err = list(list(), list(), list(), list(), list(), list())
)

for (i in 1:100){
  set.seed(i)
  
  n <- 96*2
  L <- 96
  x <- 0:(n-1)
  y1 <- sin(2*pi/12 * x)
  y2 <- cos(2*pi/3 * x)/2
  y <- y1 + y2 + rnorm(n, 0, 0.1)
  X <- hankel(y, L = L)
  eps <- 1/(n+1)
  
  s_ssa <- ssa(y[1:(n-1)], L)
  r_ssa <- reconstruct(s_ssa, groups = list(
    F1 = c(1, 2),
    F2 = c(3, 4)
  ))
  # r_ssa <- reconstruct(s_ssa, groups=list(
  #   sesonal_sin = c(1, 2),
  #   sesonal_cos = c(3, 4)
  # ))
  # plot(x[1:(n-1)], r_ssa$F1, type = "l")
  # plot(x[1:(n-1)], r_ssa$F2, type = "l")
  # plot(wcor(s_ssa, groups = 1:10), scales = list(at = c(10, 20, 30)))
  e_ssa <- eossa_new(s_ssa, nested.groups = list(1:4), clust_type = "distance")
  g_sesonal_e <- grouping.auto(e_ssa, base = "eigen",
                         freq.bins = list(
                           sesonal_sin = c(1/12-eps, 1/12+eps),
                           sesonal_cos = c(1/3-eps, 1/3+eps)
                                          ),
                         threshold = 0.5)
  r_ssa_e <- reconstruct(e_ssa, groups=g_sesonal_e)
  # plot(x, r_ssa_e$sesonal_sin)
  # plot(x, r_ssa_e$sesonal_cos)
  
  
  
  r_fft <- reconstruct_fft(x, y)
  r_fft_grouped <- grouping_cissa(r_fft,
                      groups = list(
                        sesonal_sin = c(1/12-eps, 1/12+eps),
                        sesonal_cos = c(1/3-eps, 1/3+eps)
                      )
                      )$t_series
  
  r_fft_extended <- reconstruct_fft(x, y, TRUE)
  r_fft_grouped_extended <- grouping_cissa(r_fft_extended,
                      groups = list(
                        sesonal_sin = c(1/12-eps, 1/12+eps),
                        sesonal_cos = c(1/3-eps, 1/3+eps)
                      )
                      )$t_series
  
  # r_fft_grouped$sesonal_sin |> length()
  
  # plot(x, r_fft_grouped$sesonal_sin)
  # plot(x, r_fft_grouped$sesonal_cos)
  # plot(x, r_fft_grouped$residuals)
  
  
  r_cissa <- circulant_SSA(y, L)
  r_cissa_grouped <- grouping_cissa(r_cissa,
                      groups = list(
                        sesonal_sin = c(1/12-eps, 1/12+eps),
                        sesonal_cos = c(1/3-eps, 1/3+eps)
                      )
                      )$t_series
  
  
  r_cissa_ext <- circulant_SSA(y, L, extend_flag = TRUE)
  r_cissa_grouped_ext <- grouping_cissa(r_cissa_ext,
                      groups = list(
                        sesonal_sin = c(1/12-eps, 1/12+eps),
                        sesonal_cos = c(1/3-eps, 1/3+eps)
                      )
                      )$t_series
  data$cos_err[[1]][[i]] <- 
    min(mse(y1[1:(n-1)], r_ssa$F1), mse(y1[1:(n-1)], r_ssa$F2))
  data$sin_err[[1]][[i]] <-
    min(mse(y2[1:(n-1)], r_ssa$F1), mse(y2[1:(n-1)], r_ssa$F2))
  data$all_err[[1]][[i]] <-
    min(mse(y1[1:(n-1)]+y2[1:(n-1)], r_ssa$F1+ r_ssa$F2))
  
  data$cos_err[[2]][[i]] <- mse(y1[1:(n-1)], r_ssa_e$sesonal_sin)
  data$sin_err[[2]][[i]] <- mse(y2[1:(n-1)], r_ssa_e$sesonal_cos)
  data$all_err[[2]][[i]] <- mse(y1[1:(n-1)]+ y2[1:(n-1)],
                                r_ssa_e$sesonal_sin + r_ssa_e$sesonal_cos)
  
  
  data$cos_err[[3]][[i]] <- mse(y1, r_fft_grouped$sesonal_sin)
  data$sin_err[[3]][[i]] <- mse(y2, r_fft_grouped$sesonal_cos)
  data$all_err[[3]][[i]] <- mse(y1 + y2,
                                r_fft_grouped$sesonal_cos +  r_fft_grouped$sesonal_sin)
  
  
  data$cos_err[[4]][[i]] <- mse(y1, r_cissa_grouped$sesonal_sin)
  data$sin_err[[4]][[i]] <- mse(y2, r_cissa_grouped$sesonal_cos)
  data$all_err[[4]][[i]] <- mse(y1 + y2,
                          r_cissa_grouped$sesonal_sin +  r_cissa_grouped$sesonal_cos
                                )
  
  data$cos_err[[5]][[i]] <- mse(y1, r_cissa_grouped_ext$sesonal_sin)
  data$sin_err[[5]][[i]] <- mse(y2, r_cissa_grouped_ext$sesonal_cos)
  data$all_err[[5]][[i]] <- mse(y1 + y2,
                          r_cissa_grouped_ext$sesonal_sin + r_cissa_grouped_ext$sesonal_cos
                                )
  
  data$cos_err[[6]][[i]] <- mse(y1, r_fft_grouped_extended$sesonal_sin)
  data$sin_err[[6]][[i]] <- mse(y2, r_fft_grouped_extended$sesonal_cos)
  data$all_err[[6]][[i]] <- mse(y1 + y2,
                          r_fft_grouped_extended$sesonal_sin + r_fft_grouped_extended$sesonal_cos
                                )
}
library(xtable)

# Шаг 2: Создание примера данных
data_prev <- data

data <- data.frame(
  Метод = c("SSA", "SSA EOSSA","Fourier", "CiSSA", "CiSSA extended", "Fourier extended"),
  sin_err = c(0, 0, 0, 0, 0, 0),
  cos_err = c(0, 0, 0, 0, 0, 0),
  all_err = c(0, 0, 0, 0, 0, 0)
)

data$cos_err[1] <- mean(data_prev$cos_err[[1]] |> unlist()) |>
  formatC(format = "e", digits = 1)
data$sin_err[1] <- mean(data_prev$sin_err[[1]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$all_err[1] <- mean(data_prev$all_err[[1]]|> unlist()) |>
  formatC(format = "e", digits = 1)

data$cos_err[2] <- mean(data_prev$cos_err[[2]] |> unlist()) |>
  formatC(format = "e", digits = 1)
data$sin_err[2] <- mean(data_prev$sin_err[[2]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$all_err[2] <- mean(data_prev$all_err[[2]]|> unlist()) |>
  formatC(format = "e", digits = 1)


data$cos_err[3] <- mean(data_prev$cos_err[[3]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$sin_err[3] <- mean(data_prev$sin_err[[3]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$all_err[3] <- mean(data_prev$all_err[[3]]|> unlist()) |>
  formatC(format = "e", digits = 1)


data$cos_err[4] <- mean(data_prev$cos_err[[4]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$sin_err[4] <- mean(data_prev$sin_err[[4]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$all_err[4] <- mean(data_prev$all_err[[4]]|> unlist()) |>
  formatC(format = "e", digits = 1)


data$cos_err[5] <- mean(data_prev$cos_err[[5]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$sin_err[5] <- mean(data_prev$sin_err[[5]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$all_err[5] <- mean(data_prev$all_err[[5]]|> unlist()) |>
  formatC(format = "e", digits = 1)

data$cos_err[6] <- mean(data_prev$cos_err[[6]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$sin_err[6] <- mean(data_prev$sin_err[[6]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$all_err[6] <- mean(data_prev$all_err[[6]]|> unlist()) |>
  formatC(format = "e", digits = 1)
for (i in 1:6){
  for (j in (i):6){
    x <- data_prev$cos_err[[i]] |> unlist()
    y <- data_prev$cos_err[[j]] |> unlist()
    t_test_result <- t.test(x, y, paired = TRUE)
    print(paste("cos, ", data$Метод[i], " ", data$Метод[j], ", p-val = ", t_test_result$p.value))
  }
}

for (i in 1:6){
  for (j in (i):6){
    x <- data_prev$sin_err[[i]] |> unlist()
    y <- data_prev$sin_err[[j]] |> unlist()
    t_test_result <- t.test(x, y, paired = TRUE)
    print(paste("sin, ", data$Метод[i], " ", data$Метод[j], ", p-val = ", t_test_result$p.value))
  }
}

for (i in 1:6){
  for (j in (i):6){
    x <- data_prev$all_err[[i]] |> unlist()
    y <- data_prev$all_err[[j]] |> unlist()
    t_test_result <- t.test(x, y, paired = TRUE)
    print(paste("all_err, ", data$Метод[i], " ", data$Метод[j], ", p-val = ", t_test_result$p.value))
  }
}


table_latex <- xtable(data, caption = "Example Table")

# Шаг 4: Вывод таблицы в LaTeX файл
print(table_latex, include.rownames = FALSE)

# mean(data_prev$sin_err[[2]] |> unlist()) |> print()
# mean(data_prev$sin_err[[1]] |> unlist()) |> print()

Добавим непериодичность

n <- 96*2
x <- 0:(n-1)
L <- 96
y1 <- sin(2*pi/12 * x)
y2 <- cos(2*pi/3 * x)/2
y3 <- exp(x/100) + 1
y <- y1 + y2 + y3
eps <- 1/(n+1)

s_ssa <- ssa(y[1:(n-1)], L)
r_ssa <- reconstruct(s_ssa, groups=list(
  e = c(1, 6),
  sesonal_sin = c(2, 3),
  sesonal_cos = c(4, 5),
  all = 1:6
))
# plot(x[1:(n-1)], r_ssa$e, type = "l")
# plot(x[1:(n-1)], r_ssa$sesonal_sin, type = "l")
# plot(x[1:(n-1)], r_ssa$sesonal_cos, type = "l")
# plot(wcor(s_ssa, groups = 1:10), scales = list(at = c(10, 20, 30)))
e_ssa <- eossa_new(s_ssa, nested.groups = list(1:6), clust_type = "distance")
g_sesonal_e <- grouping.auto(e_ssa, base = "eigen",
                       freq.bins = list(
                         e = c(0, 1/12-eps-eps),
                         sesonal_sin = c(1/12-eps, 1/12+eps),
                         sesonal_cos = c(1/3-eps, 1/3+eps)
                                        ),
                       threshold = 0.5)
r_ssa_e <- reconstruct(e_ssa, groups=g_sesonal_e)
# plot(x, r_ssa_e$sesonal_sin)
# plot(x, r_ssa_e$sesonal_cos)



r_fft <- reconstruct_fft(x, y)
r_fft_grouped <- grouping_cissa(r_fft,
                    groups = list(
                      e = c(0, 1/12-eps-eps),
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series

r_fft_extended <- reconstruct_fft(x, y, TRUE)
r_fft_grouped_extended <- grouping_cissa(r_fft_extended,
                    groups = list(
                      e = c(0, 1/12-eps-eps),
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series

# r_fft_grouped$sesonal_sin |> length()

# plot(x, r_fft_grouped$sesonal_sin)
# plot(x, r_fft_grouped$sesonal_cos)
# plot(x, r_fft_grouped$residuals)


r_cissa <- circulant_SSA(y, L)
r_cissa_grouped <- grouping_cissa(r_cissa,
                    groups = list(
                      e = c(0, 1/12-eps-eps),
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series


r_cissa_ext <- circulant_SSA(y, L, extend_flag = TRUE)
r_cissa_grouped_ext <- grouping_cissa(r_cissa_ext,
                    groups = list(
                      e = c(0, 1/12-eps-eps),
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series

# plot(x, r_cissa_grouped$sesonal_sin)
# plot(x, r_cissa_grouped$sesonal_cos)
# plot(x, r_cissa_grouped$residuals)

library(xtable)

# Шаг 2: Создание примера данных
data <- data.frame(
  Метод = c("SSA", "SSA EOSSA","Fourier", "CiSSA", "CiSSA extended", "Fourier extended"),
  e_err = c(1, 1, 1, 1, 1, 1),
  sin_err = c (1, 20, 20, 1, 1, 1),
  cos_err = c(1, 1, 1, 1, 1, 1),
  all_err = c(1, 1, 1, 1, 1, 1)
)

data$cos_err[1] <- mse(y1[1:(n-1)], r_ssa$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[1] <- mse(y2[1:(n-1)], r_ssa$sesonal_cos) |>
  formatC(format = "e", digits = 1)
data$e_err[1] <- mse(y3[1:(n-1)], r_ssa$e) |>
  formatC(format = "e", digits = 1)
data$all_err[1] <- mse(y1[1:(n-1)]+ y2[1:(n-1)] + y3[1:(n-1)],
                     r_ssa$all) |>
  formatC(format = "e", digits = 1)

data$cos_err[2] <- mse(y1[1:(n-1)], r_ssa_e$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[2] <- mse(y2[1:(n-1)], r_ssa_e$sesonal_cos) |>
  formatC(format = "e", digits = 1)
data$e_err[2] <- mse(y3[1:(n-1)], r_ssa_e$e) |>
  formatC(format = "e", digits = 1)
data$all_err[2] <- mse(y1[1:(n-1)]+ y2[1:(n-1)] + y3[1:(n-1)],
                     r_ssa_e$sesonal_sin + r_ssa_e$sesonal_cos + r_ssa_e$e
                       ) |>
  formatC(format = "e", digits = 1)


data$cos_err[3] <- mse(y1, r_fft_grouped$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[3] <- mse(y2, r_fft_grouped$sesonal_cos) |>
  formatC(format = "e", digits = 1)
data$e_err[3] <- mse(y3, r_fft_grouped$e) |>
  formatC(format = "e", digits = 1)
data$all_err[3] <- mse(y1 + y2 + y3, 
                       r_fft_grouped$sesonal_sin + r_fft_grouped$sesonal_cos + r_fft_grouped$e) |>
  formatC(format = "e", digits = 1)


data$cos_err[4] <- mse(y1, r_cissa_grouped$sesonal_sin) |> 
  formatC(format = "e", digits = 1)
data$sin_err[4] <- mse(y2, r_cissa_grouped$sesonal_cos) |> 
  formatC(format = "e", digits = 1)
data$e_err[4] <- mse(y3, r_cissa_grouped$e) |>
  formatC(format = "e", digits = 1)
data$all_err[4] <- mse(y1 + y2 + y3, 
                       r_cissa_grouped$sesonal_sin + 
                         r_cissa_grouped$sesonal_cos + 
                         r_cissa_grouped$e
                       ) |>
  formatC(format = "e", digits = 1)

data$cos_err[5] <- mse(y1, r_cissa_grouped_ext$sesonal_sin) |> 
  formatC(format = "e", digits = 1)
data$sin_err[5] <- mse(y2, r_cissa_grouped_ext$sesonal_cos) |> 
  formatC(format = "e", digits = 1)
data$e_err[5] <- mse(y3, r_cissa_grouped_ext$e) |>
  formatC(format = "e", digits = 1)
data$all_err[5] <- mse(y1 + y2 + y3, 
                       r_cissa_grouped_ext$sesonal_sin + 
                         r_cissa_grouped_ext$sesonal_cos +
                          r_cissa_grouped_ext$e
                       ) |>
  formatC(format = "e", digits = 1)

data$cos_err[6] <- mse(y1, r_fft_grouped_extended$sesonal_sin) |> 
  formatC(format = "e", digits = 1)
data$sin_err[6] <- mse(y2, r_fft_grouped_extended$sesonal_cos) |> 
  formatC(format = "e", digits = 1)
data$e_err[6] <- mse(y3, r_fft_grouped_extended$e) |>
  formatC(format = "e", digits = 1)
data$all_err[6] <- mse(y1 + y2 + y3, 
                       r_fft_grouped_extended$sesonal_sin +
                         r_fft_grouped_extended$sesonal_cos +
                         r_fft_grouped_extended$e
                       ) |>
  formatC(format = "e", digits = 1)



table_latex <- xtable(data, caption = "Example Table")

# Шаг 4: Вывод таблицы в LaTeX файл
print(table_latex, include.rownames = FALSE)
% latex table generated in R 4.2.2 by xtable 1.8-4 package
% Tue Mar  4 20:48:21 2025
\begin{table}[ht]
\centering
\begin{tabular}{lllll}
  \hline
Метод & e\_err & sin\_err & cos\_err & all\_err \\ 
  \hline
SSA & 6.1e-05 & 8.9e-07 & 5.2e-05 & 2.1e-28 \\ 
  SSA EOSSA & 2.3e-28 & 2.1e-29 & 9.8e-30 & 2.1e-28 \\ 
  Fourier & 1.1e-01 & 6.1e-04 & 6.8e-03 & 1.1e-01 \\ 
  CiSSA & 5.3e-02 & 1.6e-05 & 4.9e-04 & 4.4e-02 \\ 
  CiSSA extended & 5.0e-04 & 2.1e-04 & 1.1e-03 & 6.0e-04 \\ 
  Fourier extended & 1.4e-03 & 1.3e-03 & 8.4e-03 & 9.6e-03 \\ 
   \hline
\end{tabular}
\caption{Example Table} 
\end{table}

Непериодичность с шумом

# data <- data.frame(
#   Метод = c("Fourier", "CiSSA", "CiSSA с расширением ряда"),
#   sin_err = c (20, 20, 20),
#   cos_err = c(1, 1, 20),
#   exp_err = c(1, 1, 20)
# )
data <- list(
  Метод = c("SSA", "SSA EOSSA","Fourier", "CiSSA", "CiSSA extended", "Fourier extended"),
  sin_err = list(list(), list(), list(), list(), list(), list()),
  cos_err = list(list(), list(), list(), list(), list(), list()),
  exp_err = list(list(), list(), list(), list(), list(), list()),
  all_err = list(list(), list(), list(), list(), list(), list())
)

for (i in 1:100){
  set.seed(i)
  
  n <- 96*2
  x <- 0:(n-1)
  L <- 96
  y1 <- sin(2*pi/12 * x)
  y2 <- cos(2*pi/3 * x)/2
  y3 <- exp(x/100) + 1
  y <- y1 + y2 + y3 + rnorm(n, 0, 0.1)
  eps <- 1/(n+1)
  
  s_ssa <- ssa(y[1:(n-1)], L)
  r_ssa <- reconstruct(s_ssa, groups=list(
    e = 1,
    sesonal_sin = c(2, 3),
    sesonal_cos = c(4, 5)
  ))
  
  
  e_ssa <- eossa_new(s_ssa, nested.groups = list(1:7), clust_type = "distance")
  g_sesonal_e <- grouping.auto(e_ssa, base = "eigen",
                         freq.bins = list(
                           e = c(0, 1/12-eps-eps),
                           sesonal_sin = c(1/12-eps, 1/12+eps),
                           sesonal_cos = c(1/3-eps, 1/3+eps)
                                          ),
                         threshold = 0.5)
  r_ssa_e <- reconstruct(e_ssa, groups=g_sesonal_e)
  
  
  
  r_fft <- reconstruct_fft(x, y)
  r_fft_grouped <- grouping_cissa(r_fft,
                      groups = list(
                        e = c(0, 1/12-eps-eps),
                        sesonal_sin = c(1/12-eps, 1/12+eps),
                        sesonal_cos = c(1/3-eps, 1/3+eps)
                      )
                      )$t_series
  
  r_fft_extended <- reconstruct_fft(x, y, TRUE)
  r_fft_grouped_extended <- grouping_cissa(r_fft_extended,
                      groups = list(
                        e = c(0, 1/12-eps-eps),
                        sesonal_sin = c(1/12-eps, 1/12+eps),
                        sesonal_cos = c(1/3-eps, 1/3+eps)
                      )
                      )$t_series
  
  
  r_cissa <- circulant_SSA(y, L)
  r_cissa_grouped <- grouping_cissa(r_cissa,
                      groups = list(
                        e = c(0, 1/12-eps-eps),
                        sesonal_sin = c(1/12-eps, 1/12+eps),
                        sesonal_cos = c(1/3-eps, 1/3+eps)
                      )
                      )$t_series
  
  
  r_cissa_ext <- circulant_SSA(y, L, extend_flag = TRUE)
  r_cissa_grouped_ext <- grouping_cissa(r_cissa_ext,
                      groups = list(
                        e = c(0, 1/12-eps-eps),
                        sesonal_sin = c(1/12-eps, 1/12+eps),
                        sesonal_cos = c(1/3-eps, 1/3+eps)
                      )
                      )$t_series
  
  
  
  data$cos_err[[1]][[i]] <- mse(y1[1:(n-1)], r_ssa$sesonal_sin)
  data$sin_err[[1]][[i]] <- mse(y2[1:(n-1)], r_ssa$sesonal_cos)
  data$exp_err[[1]][[i]] <- mse(y3[1:(n-1)], r_ssa$e)
  data$all_err[[1]][[i]] <- mse(y1[1:(n-1)] + y2[1:(n-1)] + y3[1:(n-1)],
                                r_ssa$sesonal_sin+
                                  r_ssa$sesonal_cos +
                                  r_ssa$e
                                )
  
  data$cos_err[[2]][[i]] <- mse(y1[1:(n-1)], r_ssa_e$sesonal_sin)
  data$sin_err[[2]][[i]] <- mse(y2[1:(n-1)], r_ssa_e$sesonal_cos)
  data$exp_err[[2]][[i]] <- mse(y3[1:(n-1)], r_ssa_e$e)
  data$all_err[[2]][[i]] <- mse(y1[1:(n-1)] + y2[1:(n-1)] + y3[1:(n-1)],
                                r_ssa_e$sesonal_sin+ 
                                  r_ssa_e$sesonal_cos + 
                                  r_ssa_e$e
                                )
  
  
  # print(data$sin_err[[2]][[i]])
  
  
  data$cos_err[[3]][[i]] <- mse(y1, r_fft_grouped$sesonal_sin)
  data$sin_err[[3]][[i]] <- mse(y2, r_fft_grouped$sesonal_cos)
  data$exp_err[[3]][[i]] <- mse(y3, r_fft_grouped$e)
  data$all_err[[3]][[i]] <- mse(y1 + y2 + y3,
                                r_fft_grouped$sesonal_sin +
                                  r_fft_grouped$sesonal_cos +
                                  r_fft_grouped$e
                                )
  
  
  data$cos_err[[4]][[i]] <- mse(y1, r_cissa_grouped$sesonal_sin)
  data$sin_err[[4]][[i]] <- mse(y2, r_cissa_grouped$sesonal_cos)
  data$exp_err[[4]][[i]] <- mse(y3, r_cissa_grouped$e)
  data$all_err[[4]][[i]] <- mse(y1 + y2 + y3,
                                r_cissa_grouped$sesonal_sin +
                                  r_cissa_grouped$sesonal_cos +
                                  r_cissa_grouped$e
                                )
  
  
  data$cos_err[[5]][[i]] <- mse(y1, r_cissa_grouped_ext$sesonal_sin)
  data$sin_err[[5]][[i]] <- mse(y2, r_cissa_grouped_ext$sesonal_cos)
  data$exp_err[[5]][[i]] <- mse(y3, r_cissa_grouped_ext$e)
  data$all_err[[5]][[i]] <- mse(y1 + y2 + y3,
                                r_cissa_grouped_ext$sesonal_sin + 
                                  r_cissa_grouped_ext$sesonal_cos +
                                  r_cissa_grouped_ext$e
                                )
  
  data$cos_err[[6]][[i]] <- mse(y1, r_fft_grouped_extended$sesonal_sin)
  data$sin_err[[6]][[i]] <- mse(y2, r_fft_grouped_extended$sesonal_cos)
  data$exp_err[[6]][[i]] <- mse(y3, r_fft_grouped_extended$e)
  data$all_err[[6]][[i]] <- mse(y1 + y2 + y3,
                                r_fft_grouped_extended$sesonal_sin +
                                  r_fft_grouped_extended$sesonal_cos +
                                  r_fft_grouped_extended$e
                                )
}
library(xtable)
# data$sin_err[[2]]
# Шаг 2: Создание примера данных
data_prev <- data
data <- data.frame(
  Метод = c("SSA", "SSA EOSSA","Fourier", "CiSSA", "CiSSA extended", "Fourier extended"),
  exp_err = c(0, 0, 0, 0, 0, 0),
  sin_err = c(0, 0, 0, 0, 0, 0),
  cos_err = c(0, 0, 0, 0, 0, 0),
  all_err = c(0, 0, 0, 0, 0, 0)
)

data$cos_err[1] <- mean(data_prev$cos_err[[1]] |> unlist()) |>
  formatC(format = "e", digits = 1)
data$sin_err[1] <- mean(data_prev$sin_err[[1]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$exp_err[1] <- mean(data_prev$exp_err[[1]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$all_err[1] <- mean(data_prev$all_err[[1]]|> unlist()) |>
  formatC(format = "e", digits = 1)


data$cos_err[2] <- mean(data_prev$cos_err[[2]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$sin_err[2] <- mean(data_prev$sin_err[[2]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$exp_err[2] <- mean(data_prev$exp_err[[2]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$all_err[2] <- mean(data_prev$all_err[[2]]|> unlist()) |>
  formatC(format = "e", digits = 1)


data$cos_err[3] <- mean(data_prev$cos_err[[3]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$sin_err[3] <- mean(data_prev$sin_err[[3]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$exp_err[3] <- mean(data_prev$exp_err[[3]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$all_err[3] <- mean(data_prev$all_err[[3]]|> unlist()) |>
  formatC(format = "e", digits = 1)


data$cos_err[4] <- mean(data_prev$cos_err[[4]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$sin_err[4] <- mean(data_prev$sin_err[[4]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$exp_err[4] <- mean(data_prev$exp_err[[4]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$all_err[4] <- mean(data_prev$all_err[[4]]|> unlist()) |>
  formatC(format = "e", digits = 1)

data$cos_err[5] <- mean(data_prev$cos_err[[5]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$sin_err[5] <- mean(data_prev$sin_err[[5]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$exp_err[5] <- mean(data_prev$exp_err[[5]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$all_err[5] <- mean(data_prev$all_err[[5]]|> unlist()) |>
  formatC(format = "e", digits = 1)

data$cos_err[6] <- mean(data_prev$cos_err[[6]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$sin_err[6] <- mean(data_prev$sin_err[[6]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$exp_err[6] <- mean(data_prev$exp_err[[6]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$all_err[6] <- mean(data_prev$all_err[[6]]|> unlist()) |>
  formatC(format = "e", digits = 1)
for (i in 1:6){
  for (j in (i):6){
    x <- data_prev$cos_err[[i]] |> unlist()
    y <- data_prev$cos_err[[j]] |> unlist()
    t_test_result <- t.test(x, y, paired = TRUE)
    if (!is.na(t_test_result$p.value) & t_test_result$p.value > 0.05){
      print(paste("cos, ", data$Метод[i], " ",
                  data$Метод[j], ", p-val = ", t_test_result$p.value))
      }
  }
}

for (i in 1:6){
  for (j in (i):6){
    x <- data_prev$sin_err[[i]] |> unlist()
    y <- data_prev$sin_err[[j]] |> unlist()
    t_test_result <- t.test(x, y, paired = TRUE)
    if (!is.na(t_test_result$p.value) & t_test_result$p.value > 0.05){
      print(paste("sin, ", data$Метод[i], " ", data$Метод[j], ", p-val = ", t_test_result$p.value))
      }
  }
}

for (i in 1:6){
  for (j in (i):6){
    x <- data_prev$exp_err[[i]] |> unlist()
    y <- data_prev$exp_err[[j]] |> unlist()
    t_test_result <- t.test(x, y, paired = TRUE)
    if (!is.na(t_test_result$p.value) & t_test_result$p.value > 0.05){
      print(paste("exp, ", data$Метод[i], " ", data$Метод[j], ", p-val = ", t_test_result$p.value))}
  }
}

for (i in 1:6){
  for (j in (i):6){
    x <- data_prev$all_err[[i]] |> unlist()
    y <- data_prev$all_err[[j]] |> unlist()
    t_test_result <- t.test(x, y, paired = TRUE)
    if (!is.na(t_test_result$p.value) & t_test_result$p.value > 0.05){
      print(paste("all_err, ", data$Метод[i], " ", data$Метод[j], ", p-val = ", t_test_result$p.value))
      }
  }
}


table_latex <- xtable(data, caption = "Example Table")

# Шаг 4: Вывод таблицы в LaTeX файл
print(table_latex, include.rownames = FALSE)

Пример, который не подходит ни к какому методу

n <- 96*2 + 7
L <- 89
x <- 0:(n-1)
y1 <- sin(2*pi/13 * x)
y2 <- cos(2*pi/8 * x)
y3 <- -x*x/1000
y4 <- exp(x/55)
y <- y1 + y2 + y3 + y4 
plot(x, y)
X <- hankel(y, L = L)
eps <- 1/(n+1)

s_ssa <- ssa(y, L)
# r_ssa <- reconstruct(s_ssa, groups=list(
#   sesonal_sin = c(1, 2),
#   sesonal_cos = c(3, 4)
# ))
# plot(x, r_ssa$sesonal_sin)
# plot(x, r_ssa$sesonal_cos)
# plot(wcor(s_ssa, groups = 1:10), scales = list(at = c(10, 20, 30)))
e_ssa <- eossa_new(s_ssa, nested.groups = list(1:10), clust_type = "distance")
g_sesonal_e <- grouping.auto(e_ssa, base = "eigen",
                       freq.bins = list(
                         sesonal_sin = c(1/12-eps, 1/12+eps),
                         sesonal_cos = c(1/8-eps, 1/8+eps)
                                        ),
                       threshold = 0.5)
r_ssa_e <- reconstruct(e_ssa, groups=g_sesonal_e)
# plot(x, r_ssa_e$sesonal_sin)
# plot(x, r_ssa_e$sesonal_cos)



r_fft <- reconstruct_fft(x, y)
r_fft_grouped <- grouping_cissa(r_fft,
                    groups = list(
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/8-eps, 1/8+eps)
                    )
                    )$t_series

# r_fft_grouped$sesonal_sin |> length()

# plot(x, r_fft_grouped$sesonal_sin)
# plot(x, r_fft_grouped$sesonal_cos)
# plot(x, r_fft_grouped$residuals)


r_cissa <- circulant_SSA(y, L)
r_cissa_grouped <- grouping_cissa(r_cissa,
                    groups = list(
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/8-eps, 1/8+eps)
                    )
                    )$t_series


r_cissa_ext <- circulant_SSA(y, L, extend_flag = TRUE)
r_cissa_grouped_ext <- grouping_cissa(r_cissa_ext,
                    groups = list(
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/8-eps, 1/8+eps)
                    )
                    )$t_series

# plot(x, r_cissa_grouped$sesonal_sin)
# plot(x, r_cissa_grouped$sesonal_cos)
# plot(x, r_cissa_grouped$residuals)

library(xtable)

# Шаг 2: Создание примера данных
data <- data.frame(
  Метод = c("SSA EOSSA","Fourier", "CiSSA", "CiSSA extended"),
  sin_err = c (20, 20, 1, 1),
  cos_err = c(1, 1, 1, 1)
)

data$cos_err[1] <- mse(y1, r_ssa_e$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[1] <- mse(y2, r_ssa_e$sesonal_cos) |>
  formatC(format = "e", digits = 1)


data$cos_err[2] <- mse(y1, r_fft_grouped$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[2] <- mse(y2, r_fft_grouped$sesonal_cos) |>
  formatC(format = "e", digits = 1)


data$cos_err[3] <- mse(y1, r_cissa_grouped$sesonal_sin) |> 
  formatC(format = "e", digits = 1)
data$sin_err[3] <- mse(y2, r_cissa_grouped$sesonal_cos) |> 
  formatC(format = "e", digits = 1)


data$cos_err[4] <- mse(y1, r_cissa_grouped_ext$sesonal_sin) |> 
  formatC(format = "e", digits = 1)
data$sin_err[4] <- mse(y2, r_cissa_grouped_ext$sesonal_cos) |> 
  formatC(format = "e", digits = 1)



table_latex <- xtable(data, caption = "Example Table")

# Шаг 4: Вывод таблицы в LaTeX файл
print(table_latex, include.rownames = FALSE)

Точная разделимость. Примеры

library(Rssa)
do_one_experiment <- function(methods_list, methods_names){
  
}
n <- 96*2
L <- 96
x <- 0:(n-1)
y1 <- sin(2*pi/12 * x)
y2 <- cos(2*pi/3 * x)/2
y <- y1 + y2
X <- hankel(y, L = L)
eps <- 1/(n+1)

s_ssa <- ssa(y[1:(n-1)], L)
r_ssa <- reconstruct(s_ssa, groups = list(
  F1 = c(1, 2),
  F2 = c(3, 4)
))
# r_ssa <- reconstruct(s_ssa, groups=list(
#   sesonal_sin = c(1, 2),
#   sesonal_cos = c(3, 4)
# ))
# plot(x, r_ssa$F1, type="l")
# plot(x, r_ssa$F2, type= "l")
# plot(wcor(s_ssa, groups = 1:10), scales = list(at = c(10, 20, 30)))
e_ssa <- eossa_new(s_ssa, nested.groups = list(1:4), clust_type = "distance")
g_sesonal_e <- grouping.auto(e_ssa, base = "eigen",
                       freq.bins = list(
                         sesonal_sin = c(1/12-eps, 1/12+eps),
                         sesonal_cos = c(1/3-eps, 1/3+eps)
                                        ),
                       threshold = 0.5)
r_ssa_e <- reconstruct(e_ssa, groups=g_sesonal_e)
# plot(x, r_ssa_e$sesonal_sin)
# plot(x, r_ssa_e$sesonal_cos)



r_fft <- reconstruct_fft(x, y)
r_fft_grouped <- grouping_cissa(r_fft,
                    groups = list(
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series

r_fft_extended <- reconstruct_fft(x, y, TRUE)
r_fft_grouped_extended <- grouping_cissa(r_fft_extended,
                    groups = list(
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series

# r_fft_grouped$sesonal_sin |> length()

# plot(x, r_fft_grouped$sesonal_sin)
# plot(x, r_fft_grouped$sesonal_cos)
# plot(x, r_fft_grouped$residuals)


r_cissa <- circulant_SSA(y, L)
r_cissa_grouped <- grouping_cissa(r_cissa,
                    groups = list(
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series


r_cissa_ext <- circulant_SSA(y, L, extend_flag = TRUE)
r_cissa_grouped_ext <- grouping_cissa(r_cissa_ext,
                    groups = list(
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series






# plot(x, r_cissa_grouped$sesonal_sin)
# plot(x, r_cissa_grouped$sesonal_cos)
# plot(x, r_cissa_grouped$residuals)

library(xtable)

# Шаг 2: Создание примера данных
data <- data.frame(
  Метод = c("SSA, \nLw, Kw in N", "SSA EOSSA, \nLw, Kw in N","Fourier, Nw in N", "CiSSA, Lw in N", "CiSSA extended, Lw in N", "Fourier extended, Nw in N",
            "SSA, \nLw in N, Kw not in N", "SSA EOSSA, \nLw in N, Kw not in N","Fourier, Nw not in N", "CiSSA, Lw not in N", "CiSSA extended, Lw not in N", "Fourier extended, Nw not in N"),
  sin_err = c (1, 20, 20, 1, 1, 1, 1, 20, 20, 1, 1, 1),
  cos_err = c(1, 1, 1, 1, 1, 1, 1, 20, 20, 1, 1, 1),
  all_err = c(1, 1, 1, 1, 1, 1, 1, 20, 20, 1, 1, 1)
)

data$sin_err[1] <- mse(y1[1:(n-1)], r_ssa$F1) |>
  formatC(format = "e", digits = 1) 
data$cos_err[1] <- mse(y2[1:(n-1)], r_ssa$F2) |>
  formatC(format = "e", digits = 1)
data$all_err[1] <- mse(y1[1:(n-1)] + y2[1:(n-1)], r_ssa$F1 + r_ssa$F2) |>
  formatC(format = "e", digits = 1)

data$cos_err[2] <- mse(y1[1:(n-1)], r_ssa_e$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[2] <- mse(y2[1:(n-1)], r_ssa_e$sesonal_cos) |>
  formatC(format = "e", digits = 1)
data$all_err[2] <- mse(y1[1:(n-1)] + y2[1:(n-1)],
                       r_ssa_e$sesonal_sin + r_ssa_e$sesonal_cos) |>
  formatC(format = "e", digits = 1)


data$cos_err[3] <- mse(y1, r_fft_grouped$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[3] <- mse(y2, r_fft_grouped$sesonal_cos) |>
  formatC(format = "e", digits = 1)
data$all_err[3] <- mse(y1 + y2,
                       r_fft_grouped$sesonal_sin + r_fft_grouped$sesonal_cos
                       ) |>
  formatC(format = "e", digits = 1)


data$cos_err[4] <- mse(y1, r_cissa_grouped$sesonal_sin) |> 
  formatC(format = "e", digits = 1)
data$sin_err[4] <- mse(y2, r_cissa_grouped$sesonal_cos) |> 
  formatC(format = "e", digits = 1)
data$all_err[4] <- mse(y1 + y2,
                       r_cissa_grouped$sesonal_sin + r_cissa_grouped$sesonal_cos
                       ) |>
  formatC(format = "e", digits = 1)


data$cos_err[5] <- mse(y1, r_cissa_grouped_ext$sesonal_sin) |> 
  formatC(format = "e", digits = 1)
data$sin_err[5] <- mse(y2, r_cissa_grouped_ext$sesonal_cos) |> 
  formatC(format = "e", digits = 1)
data$all_err[5] <- mse(y1 + y2,
                       r_cissa_grouped_ext$sesonal_sin + r_cissa_grouped_ext$sesonal_cos
                       ) |>
  formatC(format = "e", digits = 1)


data$cos_err[6] <- mse(y1, r_fft_grouped_extended$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[6] <- mse(y2, r_fft_grouped_extended$sesonal_cos) |>
  formatC(format = "e", digits = 1)
data$all_err[6] <- mse(y1 + y2,
                       r_fft_grouped_extended$sesonal_sin + r_fft_grouped_extended$sesonal_cos
                       ) |>
  formatC(format = "e", digits = 1)



#------------------

eps <- eps*2

s_ssa <- ssa(y, L)
r_ssa <- reconstruct(s_ssa, groups = list(
  F1 = c(1, 2),
  F2 = c(3, 4)
))
# r_ssa <- reconstruct(s_ssa, groups=list(
#   sesonal_sin = c(1, 2),
#   sesonal_cos = c(3, 4)
# ))
# plot(x, r_ssa$F1, type="l")
# plot(x, r_ssa$F2, type= "l")
# plot(wcor(s_ssa, groups = 1:10), scales = list(at = c(10, 20, 30)))
e_ssa <- eossa_new(s_ssa, nested.groups = list(1:4), clust_type = "distance")
g_sesonal_e <- grouping.auto(e_ssa, base = "eigen",
                       freq.bins = list(
                         sesonal_sin = c(1/12-eps, 1/12+eps),
                         sesonal_cos = c(1/3-eps, 1/3+eps)
                                        ),
                       threshold = 0.5)
r_ssa_e <- reconstruct(e_ssa, groups=g_sesonal_e)
# plot(x, r_ssa_e$sesonal_sin)
# plot(x, r_ssa_e$sesonal_cos)



r_fft <- reconstruct_fft(x[1:(n-1)], y[1:(n-1)])
r_fft_grouped <- grouping_cissa(r_fft,
                    groups = list(
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series

r_fft_extended <- reconstruct_fft(x[1:(n-1)], y[1:(n-1)], TRUE)
r_fft_grouped_extended <- grouping_cissa(r_fft_extended,
                    groups = list(
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series

# r_fft_grouped$sesonal_sin |> length()

# plot(x, r_fft_grouped$sesonal_sin)
# plot(x, r_fft_grouped$sesonal_cos)
# plot(x, r_fft_grouped$residuals)


r_cissa <- circulant_SSA(y, L+1)
r_cissa_grouped <- grouping_cissa(r_cissa,
                    groups = list(
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series


r_cissa_ext <- circulant_SSA(y, L+1, extend_flag = TRUE)
r_cissa_grouped_ext <- grouping_cissa(r_cissa_ext,
                    groups = list(
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series





data$sin_err[7] <- mse(y1, r_ssa$F1) |>
  formatC(format = "e", digits = 1) 
data$cos_err[7] <- mse(y2, r_ssa$F2) |>
  formatC(format = "e", digits = 1)
data$all_err[7] <- mse(y1 + y2, r_ssa$F1 + r_ssa$F2) |>
  formatC(format = "e", digits = 1)

data$cos_err[8] <- mse(y1, r_ssa_e$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[8] <- mse(y2, r_ssa_e$sesonal_cos) |>
  formatC(format = "e", digits = 1)
data$all_err[8] <- mse(y1 + y2,
                       r_ssa_e$sesonal_sin + r_ssa_e$sesonal_cos) |>
  formatC(format = "e", digits = 1)


data$cos_err[9] <- mse(y1[1:(n-1)], r_fft_grouped$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[9] <- mse(y2[1:(n-1)], r_fft_grouped$sesonal_cos) |>
  formatC(format = "e", digits = 1)
data$all_err[9] <- mse(y1[1:(n-1)] + y2[1:(n-1)],
                       r_fft_grouped$sesonal_sin + r_fft_grouped$sesonal_cos
                       ) |>
  formatC(format = "e", digits = 1)


data$cos_err[10] <- mse(y1, r_cissa_grouped$sesonal_sin) |> 
  formatC(format = "e", digits = 1)
data$sin_err[10] <- mse(y2, r_cissa_grouped$sesonal_cos) |> 
  formatC(format = "e", digits = 1)
data$all_err[10] <- mse(y1 + y2,
                       r_cissa_grouped$sesonal_sin + r_cissa_grouped$sesonal_cos
                       ) |>
  formatC(format = "e", digits = 1)


data$cos_err[11] <- mse(y1, r_cissa_grouped_ext$sesonal_sin) |> 
  formatC(format = "e", digits = 1)
data$sin_err[11] <- mse(y2, r_cissa_grouped_ext$sesonal_cos) |> 
  formatC(format = "e", digits = 1)
data$all_err[11] <- mse(y1 + y2,
                       r_cissa_grouped_ext$sesonal_sin + r_cissa_grouped_ext$sesonal_cos
                       ) |>
  formatC(format = "e", digits = 1)


data$cos_err[12] <- mse(y1[1:(n-1)], r_fft_grouped_extended$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[12] <- mse(y2[1:(n-1)], r_fft_grouped_extended$sesonal_cos) |>
  formatC(format = "e", digits = 1)
data$all_err[12] <- mse(y1[1:(n-1)] + y2[1:(n-1)],
                       r_fft_grouped_extended$sesonal_sin + r_fft_grouped_extended$sesonal_cos
                       ) |>
  formatC(format = "e", digits = 1)






table_latex <- xtable(data, caption = "Example Table")

# Шаг 4: Вывод таблицы в LaTeX файл
print(table_latex, include.rownames = FALSE)

Те же примеры с шумом

data <- list(
  Метод = c("SSA","SSA EOSSA","Fourier", "CiSSA", "CiSSA extended", "Fourier extended"),
  sin_err = list(list(), list(), list(), list(), list(), list()),
  cos_err = list(list(), list(), list(), list(), list(), list()),
  all_err = list(list(), list(), list(), list(), list(), list())
)

for (i in 1:100){
  set.seed(i)
  
  n <- 96*2
  L <- 96
  x <- 0:(n-1)
  y1 <- sin(2*pi/12 * x)
  y2 <- cos(2*pi/3 * x)/2
  y <- y1 + y2 + rnorm(n, 0, 0.1)
  X <- hankel(y, L = L)
  eps <- 1/(n+1)
  
  s_ssa <- ssa(y[1:(n-1)], L)
  r_ssa <- reconstruct(s_ssa, groups = list(
    F1 = c(1, 2),
    F2 = c(3, 4)
  ))
  # r_ssa <- reconstruct(s_ssa, groups=list(
  #   sesonal_sin = c(1, 2),
  #   sesonal_cos = c(3, 4)
  # ))
  # plot(x[1:(n-1)], r_ssa$F1, type = "l")
  # plot(x[1:(n-1)], r_ssa$F2, type = "l")
  # plot(wcor(s_ssa, groups = 1:10), scales = list(at = c(10, 20, 30)))
  e_ssa <- eossa_new(s_ssa, nested.groups = list(1:4), clust_type = "distance")
  g_sesonal_e <- grouping.auto(e_ssa, base = "eigen",
                         freq.bins = list(
                           sesonal_sin = c(1/12-eps, 1/12+eps),
                           sesonal_cos = c(1/3-eps, 1/3+eps)
                                          ),
                         threshold = 0.5)
  r_ssa_e <- reconstruct(e_ssa, groups=g_sesonal_e)
  # plot(x, r_ssa_e$sesonal_sin)
  # plot(x, r_ssa_e$sesonal_cos)
  
  
  
  r_fft <- reconstruct_fft(x, y)
  r_fft_grouped <- grouping_cissa(r_fft,
                      groups = list(
                        sesonal_sin = c(1/12-eps, 1/12+eps),
                        sesonal_cos = c(1/3-eps, 1/3+eps)
                      )
                      )$t_series
  
  r_fft_extended <- reconstruct_fft(x, y, TRUE)
  r_fft_grouped_extended <- grouping_cissa(r_fft_extended,
                      groups = list(
                        sesonal_sin = c(1/12-eps, 1/12+eps),
                        sesonal_cos = c(1/3-eps, 1/3+eps)
                      )
                      )$t_series
  
  # r_fft_grouped$sesonal_sin |> length()
  
  # plot(x, r_fft_grouped$sesonal_sin)
  # plot(x, r_fft_grouped$sesonal_cos)
  # plot(x, r_fft_grouped$residuals)
  
  
  r_cissa <- circulant_SSA(y, L)
  r_cissa_grouped <- grouping_cissa(r_cissa,
                      groups = list(
                        sesonal_sin = c(1/12-eps, 1/12+eps),
                        sesonal_cos = c(1/3-eps, 1/3+eps)
                      )
                      )$t_series
  
  
  r_cissa_ext <- circulant_SSA(y, L, extend_flag = TRUE)
  r_cissa_grouped_ext <- grouping_cissa(r_cissa_ext,
                      groups = list(
                        sesonal_sin = c(1/12-eps, 1/12+eps),
                        sesonal_cos = c(1/3-eps, 1/3+eps)
                      )
                      )$t_series
  data$cos_err[[1]][[i]] <- 
    min(mse(y1[1:(n-1)], r_ssa$F1), mse(y1[1:(n-1)], r_ssa$F2))
  data$sin_err[[1]][[i]] <-
    min(mse(y2[1:(n-1)], r_ssa$F1), mse(y2[1:(n-1)], r_ssa$F2))
  data$all_err[[1]][[i]] <-
    min(mse(y1[1:(n-1)]+y2[1:(n-1)], r_ssa$F1+ r_ssa$F2))
  
  data$cos_err[[2]][[i]] <- mse(y1[1:(n-1)], r_ssa_e$sesonal_sin)
  data$sin_err[[2]][[i]] <- mse(y2[1:(n-1)], r_ssa_e$sesonal_cos)
  data$all_err[[2]][[i]] <- mse(y1[1:(n-1)]+ y2[1:(n-1)],
                                r_ssa_e$sesonal_sin + r_ssa_e$sesonal_cos)
  
  
  data$cos_err[[3]][[i]] <- mse(y1, r_fft_grouped$sesonal_sin)
  data$sin_err[[3]][[i]] <- mse(y2, r_fft_grouped$sesonal_cos)
  data$all_err[[3]][[i]] <- mse(y1 + y2,
                                r_fft_grouped$sesonal_cos +  r_fft_grouped$sesonal_sin)
  
  
  data$cos_err[[4]][[i]] <- mse(y1, r_cissa_grouped$sesonal_sin)
  data$sin_err[[4]][[i]] <- mse(y2, r_cissa_grouped$sesonal_cos)
  data$all_err[[4]][[i]] <- mse(y1 + y2,
                          r_cissa_grouped$sesonal_sin +  r_cissa_grouped$sesonal_cos
                                )
  
  data$cos_err[[5]][[i]] <- mse(y1, r_cissa_grouped_ext$sesonal_sin)
  data$sin_err[[5]][[i]] <- mse(y2, r_cissa_grouped_ext$sesonal_cos)
  data$all_err[[5]][[i]] <- mse(y1 + y2,
                          r_cissa_grouped_ext$sesonal_sin + r_cissa_grouped_ext$sesonal_cos
                                )
  
  data$cos_err[[6]][[i]] <- mse(y1, r_fft_grouped_extended$sesonal_sin)
  data$sin_err[[6]][[i]] <- mse(y2, r_fft_grouped_extended$sesonal_cos)
  data$all_err[[6]][[i]] <- mse(y1 + y2,
                          r_fft_grouped_extended$sesonal_sin + r_fft_grouped_extended$sesonal_cos
                                )
}
library(xtable)

# Шаг 2: Создание примера данных
data_prev <- data

data <- data.frame(
  Метод = c("SSA", "SSA EOSSA","Fourier", "CiSSA", "CiSSA extended", "Fourier extended"),
  sin_err = c(0, 0, 0, 0, 0, 0),
  cos_err = c(0, 0, 0, 0, 0, 0),
  all_err = c(0, 0, 0, 0, 0, 0)
)

data$cos_err[1] <- mean(data_prev$cos_err[[1]] |> unlist()) |>
  formatC(format = "e", digits = 1)
data$sin_err[1] <- mean(data_prev$sin_err[[1]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$all_err[1] <- mean(data_prev$all_err[[1]]|> unlist()) |>
  formatC(format = "e", digits = 1)

data$cos_err[2] <- mean(data_prev$cos_err[[2]] |> unlist()) |>
  formatC(format = "e", digits = 1)
data$sin_err[2] <- mean(data_prev$sin_err[[2]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$all_err[2] <- mean(data_prev$all_err[[2]]|> unlist()) |>
  formatC(format = "e", digits = 1)


data$cos_err[3] <- mean(data_prev$cos_err[[3]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$sin_err[3] <- mean(data_prev$sin_err[[3]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$all_err[3] <- mean(data_prev$all_err[[3]]|> unlist()) |>
  formatC(format = "e", digits = 1)


data$cos_err[4] <- mean(data_prev$cos_err[[4]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$sin_err[4] <- mean(data_prev$sin_err[[4]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$all_err[4] <- mean(data_prev$all_err[[4]]|> unlist()) |>
  formatC(format = "e", digits = 1)


data$cos_err[5] <- mean(data_prev$cos_err[[5]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$sin_err[5] <- mean(data_prev$sin_err[[5]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$all_err[5] <- mean(data_prev$all_err[[5]]|> unlist()) |>
  formatC(format = "e", digits = 1)

data$cos_err[6] <- mean(data_prev$cos_err[[6]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$sin_err[6] <- mean(data_prev$sin_err[[6]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$all_err[6] <- mean(data_prev$all_err[[6]]|> unlist()) |>
  formatC(format = "e", digits = 1)

Ассимптотическая разделимость (бесполезно)


n <- 96*2
x <- 0:(n-1)
L <- 96
y1 <- sin(2*pi/12 * x)
y2 <- cos(2*pi/3 * x)/2
y3 <- exp(x/10) + 1 
y <- y1 + y2 + y3
eps <- 1/(n+1)

s_ssa <- ssa(y[1:(n-1)], L)
r_ssa <- reconstruct(s_ssa, groups=list(
  e = c(1),
  sesonal_sin = c(2, 3),
  sesonal_cos = c(4, 5)
))
# plot(x[1:(n-1)], r_ssa$e, type = "l")
# plot(x[1:(n-1)], r_ssa$sesonal_sin, type = "l")
# plot(x[1:(n-1)], r_ssa$sesonal_cos, type = "l")
# plot(wcor(s_ssa, groups = 1:10), scales = list(at = c(10, 20, 30)))
e_ssa <- eossa_new(s_ssa, nested.groups = list(1:7), clust_type = "distance")
g_sesonal_e <- grouping.auto(e_ssa, base = "eigen",
                       freq.bins = list(
                         e = c(0, 1/12-eps-eps),
                         sesonal_sin = c(1/12-eps, 1/12+eps),
                         sesonal_cos = c(1/3-eps, 1/3+eps)
                                        ),
                       threshold = 0.5)
r_ssa_e <- reconstruct(e_ssa, groups=g_sesonal_e)
# plot(x, r_ssa_e$sesonal_sin)
# plot(x, r_ssa_e$sesonal_cos)



r_fft <- reconstruct_fft(x, y)
r_fft_grouped <- grouping_cissa(r_fft,
                    groups = list(
                      e = c(0, 1/12-eps-eps),
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series

r_fft_extended <- reconstruct_fft(x, y, TRUE)
r_fft_grouped_extended <- grouping_cissa(r_fft_extended,
                    groups = list(
                      e = c(0, 1/12-eps-eps),
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series

# r_fft_grouped$sesonal_sin |> length()

# plot(x, r_fft_grouped$sesonal_sin)
# plot(x, r_fft_grouped$sesonal_cos)
# plot(x, r_fft_grouped$residuals)


r_cissa <- circulant_SSA(y, L)
r_cissa_grouped <- grouping_cissa(r_cissa,
                    groups = list(
                      e = c(0, 1/12-eps-eps),
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series


r_cissa_ext <- circulant_SSA(y, L, extend_flag = TRUE)
r_cissa_grouped_ext <- grouping_cissa(r_cissa_ext,
                    groups = list(
                      e = c(0, 1/12-eps-eps),
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series

# plot(x, r_cissa_grouped$sesonal_sin)
# plot(x, r_cissa_grouped$sesonal_cos)
# plot(x, r_cissa_grouped$residuals)

library(xtable)

# Шаг 2: Создание примера данных
data <- data.frame(
  Метод = c("SSA", "SSA EOSSA","Fourier", "CiSSA", "CiSSA extended", "Fourier extended"),
  e_err = c(1, 1, 1, 1, 1, 1),
  sin_err = c (1, 20, 20, 1, 1, 1),
  cos_err = c(1, 1, 1, 1, 1, 1),
  all_err = c(1, 1, 1, 1, 1, 1)
)

data$cos_err[1] <- mse(y1[1:(n-1)], r_ssa$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[1] <- mse(y2[1:(n-1)], r_ssa$sesonal_cos) |>
  formatC(format = "e", digits = 1)
data$e_err[1] <- mse(y3[1:(n-1)], r_ssa$e) |>
  formatC(format = "e", digits = 1)
data$all_err[1] <- mse(y1[1:(n-1)]+ y2[1:(n-1)] + y3[1:(n-1)],
                     r_ssa$sesonal_sin + r_ssa$sesonal_cos + r_ssa$e) |>
  formatC(format = "e", digits = 1)

data$cos_err[2] <- mse(y1[1:(n-1)], r_ssa_e$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[2] <- mse(y2[1:(n-1)], r_ssa_e$sesonal_cos) |>
  formatC(format = "e", digits = 1)
data$e_err[2] <- mse(y3[1:(n-1)], r_ssa_e$e) |>
  formatC(format = "e", digits = 1)
data$all_err[2] <- mse(y1[1:(n-1)]+ y2[1:(n-1)] + y3[1:(n-1)],
                     r_ssa_e$sesonal_sin + r_ssa_e$sesonal_cos + r_ssa_e$e
                       ) |>
  formatC(format = "e", digits = 1)


data$cos_err[3] <- mse(y1, r_fft_grouped$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[3] <- mse(y2, r_fft_grouped$sesonal_cos) |>
  formatC(format = "e", digits = 1)
data$e_err[3] <- mse(y3, r_fft_grouped$e) |>
  formatC(format = "e", digits = 1)
data$all_err[3] <- mse(y1 + y2 + y3, 
                       r_fft_grouped$sesonal_sin + r_fft_grouped$sesonal_cos + r_fft_grouped$e) |>
  formatC(format = "e", digits = 1)


data$cos_err[4] <- mse(y1, r_cissa_grouped$sesonal_sin) |> 
  formatC(format = "e", digits = 1)
data$sin_err[4] <- mse(y2, r_cissa_grouped$sesonal_cos) |> 
  formatC(format = "e", digits = 1)
data$e_err[4] <- mse(y3, r_cissa_grouped$e) |>
  formatC(format = "e", digits = 1)
data$all_err[4] <- mse(y1 + y2 + y3, 
                       r_cissa_grouped$sesonal_sin + 
                         r_cissa_grouped$sesonal_cos + 
                         r_cissa_grouped$e
                       ) |>
  formatC(format = "e", digits = 1)

data$cos_err[5] <- mse(y1, r_cissa_grouped_ext$sesonal_sin) |> 
  formatC(format = "e", digits = 1)
data$sin_err[5] <- mse(y2, r_cissa_grouped_ext$sesonal_cos) |> 
  formatC(format = "e", digits = 1)
data$e_err[5] <- mse(y3, r_cissa_grouped_ext$e) |>
  formatC(format = "e", digits = 1)
data$all_err[5] <- mse(y1 + y2 + y3, 
                       r_cissa_grouped_ext$sesonal_sin + 
                         r_cissa_grouped_ext$sesonal_cos +
                          r_cissa_grouped_ext$e
                       ) |>
  formatC(format = "e", digits = 1)

data$cos_err[6] <- mse(y1, r_fft_grouped_extended$sesonal_sin) |> 
  formatC(format = "e", digits = 1)
data$sin_err[6] <- mse(y2, r_fft_grouped_extended$sesonal_cos) |> 
  formatC(format = "e", digits = 1)
data$e_err[6] <- mse(y3, r_fft_grouped_extended$e) |>
  formatC(format = "e", digits = 1)
data$all_err[6] <- mse(y1 + y2 + y3, 
                       r_fft_grouped_extended$sesonal_sin +
                         r_fft_grouped_extended$sesonal_cos +
                         r_fft_grouped_extended$e
                       ) |>
  formatC(format = "e", digits = 1)



table_latex <- xtable(data, caption = "Example Table")

# Шаг 4: Вывод таблицы в LaTeX файл
print(table_latex, include.rownames = FALSE)

Несколько непериодик

n <- 96*2
x <- 0:(n-1)
L <- 96
y1 <- sin(2*pi/12 * x)
y2 <- cos(2*pi/3 * x)/2
y3 <- exp(x/100) + 1
y <- y1 + y2 + y3
eps <- 1/(n+1)

s_ssa <- ssa(y[1:(n-1)], L)
r_ssa <- reconstruct(s_ssa, groups=list(
  e = c(1),
  sesonal_sin = c(2, 3),
  sesonal_cos = c(4, 5)
))
# plot(x[1:(n-1)], r_ssa$e, type = "l")
# plot(x[1:(n-1)], r_ssa$sesonal_sin, type = "l")
# plot(x[1:(n-1)], r_ssa$sesonal_cos, type = "l")
# plot(wcor(s_ssa, groups = 1:10), scales = list(at = c(10, 20, 30)))
e_ssa <- eossa_new(s_ssa, nested.groups = list(1:10), clust_type = "distance")
g_sesonal_e <- grouping.auto(e_ssa, base = "eigen",
                       freq.bins = list(
                         e = c(0, 1/12-eps-eps),
                         sesonal_sin = c(1/12-eps, 1/12+eps),
                         sesonal_cos = c(1/3-eps, 1/3+eps)
                                        ),
                       threshold = 0.5)
r_ssa_e <- reconstruct(e_ssa, groups=g_sesonal_e)
r_ssa_e
# plot(x, r_ssa_e$sesonal_sin)
# plot(x, r_ssa_e$sesonal_cos)



r_fft <- reconstruct_fft(x, y)
r_fft_grouped <- grouping_cissa(r_fft,
                    groups = list(
                      e = c(0, 1/12-eps-eps),
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series

r_fft_extended <- reconstruct_fft(x, y, TRUE)
r_fft_grouped_extended <- grouping_cissa(r_fft_extended,
                    groups = list(
                      e = c(0, 1/12-eps-eps),
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series

# r_fft_grouped$sesonal_sin |> length()

# plot(x, r_fft_grouped$sesonal_sin)
# plot(x, r_fft_grouped$sesonal_cos)
# plot(x, r_fft_grouped$residuals)


r_cissa <- circulant_SSA(y, L)
r_cissa_grouped <- grouping_cissa(r_cissa,
                    groups = list(
                      e = c(0, 1/12-eps-eps),
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series


r_cissa_ext <- circulant_SSA(y, L, extend_flag = TRUE)
r_cissa_grouped_ext <- grouping_cissa(r_cissa_ext,
                    groups = list(
                      e = c(0, 1/12-eps-eps),
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series

# plot(x, r_cissa_grouped$sesonal_sin)
# plot(x, r_cissa_grouped$sesonal_cos)
# plot(x, r_cissa_grouped$residuals)

library(xtable)

# Шаг 2: Создание примера данных
data <- data.frame(
  Метод = c("SSA", "SSA EOSSA","Fourier", "CiSSA", "CiSSA extended", "Fourier extended"),
  e_err = c(1, 1, 1, 1, 1, 1),
  sin_err = c (1, 20, 20, 1, 1, 1),
  cos_err = c(1, 1, 1, 1, 1, 1),
  all_err = c(1, 1, 1, 1, 1, 1)
)

data$cos_err[1] <- mse(y1[1:(n-1)], r_ssa$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[1] <- mse(y2[1:(n-1)], r_ssa$sesonal_cos) |>
  formatC(format = "e", digits = 1)
data$e_err[1] <- mse(y3[1:(n-1)], r_ssa$e) |>
  formatC(format = "e", digits = 1)
data$all_err[1] <- mse(y1[1:(n-1)]+ y2[1:(n-1)] + y3[1:(n-1)],
                     r_ssa$sesonal_sin + r_ssa$sesonal_cos + r_ssa$e) |>
  formatC(format = "e", digits = 1)

data$cos_err[2] <- mse(y1[1:(n-1)], r_ssa_e$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[2] <- mse(y2[1:(n-1)], r_ssa_e$sesonal_cos) |>
  formatC(format = "e", digits = 1)
data$e_err[2] <- mse(y3[1:(n-1)], r_ssa_e$e) |>
  formatC(format = "e", digits = 1)
data$all_err[2] <- mse(y1[1:(n-1)]+ y2[1:(n-1)] + y3[1:(n-1)],
                     r_ssa_e$sesonal_sin + r_ssa_e$sesonal_cos + r_ssa_e$e
                       ) |>
  formatC(format = "e", digits = 1)


data$cos_err[3] <- mse(y1, r_fft_grouped$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[3] <- mse(y2, r_fft_grouped$sesonal_cos) |>
  formatC(format = "e", digits = 1)
data$e_err[3] <- mse(y3, r_fft_grouped$e) |>
  formatC(format = "e", digits = 1)
data$all_err[3] <- mse(y1 + y2 + y3, 
                       r_fft_grouped$sesonal_sin + r_fft_grouped$sesonal_cos + r_fft_grouped$e) |>
  formatC(format = "e", digits = 1)


data$cos_err[4] <- mse(y1, r_cissa_grouped$sesonal_sin) |> 
  formatC(format = "e", digits = 1)
data$sin_err[4] <- mse(y2, r_cissa_grouped$sesonal_cos) |> 
  formatC(format = "e", digits = 1)
data$e_err[4] <- mse(y3, r_cissa_grouped$e) |>
  formatC(format = "e", digits = 1)
data$all_err[4] <- mse(y1 + y2 + y3, 
                       r_cissa_grouped$sesonal_sin + 
                         r_cissa_grouped$sesonal_cos + 
                         r_cissa_grouped$e
                       ) |>
  formatC(format = "e", digits = 1)

data$cos_err[5] <- mse(y1, r_cissa_grouped_ext$sesonal_sin) |> 
  formatC(format = "e", digits = 1)
data$sin_err[5] <- mse(y2, r_cissa_grouped_ext$sesonal_cos) |> 
  formatC(format = "e", digits = 1)
data$e_err[5] <- mse(y3, r_cissa_grouped_ext$e) |>
  formatC(format = "e", digits = 1)
data$all_err[5] <- mse(y1 + y2 + y3, 
                       r_cissa_grouped_ext$sesonal_sin + 
                         r_cissa_grouped_ext$sesonal_cos +
                          r_cissa_grouped_ext$e
                       ) |>
  formatC(format = "e", digits = 1)

data$cos_err[6] <- mse(y1, r_fft_grouped_extended$sesonal_sin) |> 
  formatC(format = "e", digits = 1)
data$sin_err[6] <- mse(y2, r_fft_grouped_extended$sesonal_cos) |> 
  formatC(format = "e", digits = 1)
data$e_err[6] <- mse(y3, r_fft_grouped_extended$e) |>
  formatC(format = "e", digits = 1)
data$all_err[6] <- mse(y1 + y2 + y3, 
                       r_fft_grouped_extended$sesonal_sin +
                         r_fft_grouped_extended$sesonal_cos +
                         r_fft_grouped_extended$e
                       ) |>
  formatC(format = "e", digits = 1)



table_latex <- xtable(data, caption = "Example Table")

# Шаг 4: Вывод таблицы в LaTeX файл
print(table_latex, include.rownames = FALSE)

Выделение тренда

n <- 96*2
x <- 0:(n-1)
L <- 96
y1 <- sin(2*pi/12 * x)
y2 <- cos(2*pi/3 * x)/2
y3 <- exp(x/100) + 1
y <- y1 + y2 + y3
eps <- 1/(n+1)

s_ssa <- ssa(y, L)
r_ssa <- reconstruct(s_ssa, groups=list(
  e = c(1, 6),
  sesonal_sin = c(2, 3),
  sesonal_cos = c(4, 5),
  all = 1:6
))
# plot(x[1:(n-1)], r_ssa$e, type = "l")
# plot(x[1:(n-1)], r_ssa$sesonal_sin, type = "l")
# plot(x[1:(n-1)], r_ssa$sesonal_cos, type = "l")
# plot(wcor(s_ssa, groups = 1:10), scales = list(at = c(10, 20, 30)))
e_ssa <- eossa_new(s_ssa, nested.groups = list(1:6), clust_type = "distance")
g_sesonal_e <- grouping.auto(e_ssa, base = "eigen",
                       freq.bins = list(
                         e = c(0, 1/12-eps-eps),
                         sesonal_sin = c(1/12-eps, 1/12+eps),
                         sesonal_cos = c(1/3-eps, 1/3+eps)
                                        ),
                       threshold = 0.5)
r_ssa_e <- reconstruct(e_ssa, groups=g_sesonal_e)
# plot(x, r_ssa_e$sesonal_sin)
# plot(x, r_ssa_e$sesonal_cos)



r_fft <- reconstruct_fft(x[1:(n-1)], y[1:(n-1)])
r_fft_grouped <- grouping_cissa(r_fft,
                    groups = list(
                      e = c(0, 1/12-eps-eps),
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series

r_fft_extended <- reconstruct_fft(x[1:(n-1)], y[1:(n-1)], TRUE)
r_fft_grouped_extended <- grouping_cissa(r_fft_extended,
                    groups = list(
                      e = c(0, 1/12-eps-eps),
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series

# r_fft_grouped$sesonal_sin |> length()

# plot(x, r_fft_grouped$sesonal_sin)
# plot(x, r_fft_grouped$sesonal_cos)
# plot(x, r_fft_grouped$residuals)


r_cissa <- circulant_SSA(y, L+1)
r_cissa_grouped <- grouping_cissa(r_cissa,
                    groups = list(
                      e = c(0, 1/12-eps-eps),
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series


r_cissa_ext <- circulant_SSA(y, L+1, extend_flag = TRUE)
r_cissa_grouped_ext <- grouping_cissa(r_cissa_ext,
                    groups = list(
                      e = c(0, 1/12-eps-eps),
                      sesonal_sin = c(1/12-eps, 1/12+eps),
                      sesonal_cos = c(1/3-eps, 1/3+eps)
                    )
                    )$t_series

# plot(x, r_cissa_grouped$sesonal_sin)
# plot(x, r_cissa_grouped$sesonal_cos)
# plot(x, r_cissa_grouped$residuals)

library(xtable)

# Шаг 2: Создание примера данных
data <- data.frame(
  Метод = c("SSA", "SSA EOSSA","Fourier", "CiSSA", "CiSSA extended", "Fourier extended"),
  e_err = c(1, 1, 1, 1, 1, 1),
  sin_err = c (1, 20, 20, 1, 1, 1),
  cos_err = c(1, 1, 1, 1, 1, 1),
  all_err = c(1, 1, 1, 1, 1, 1)
)

data$cos_err[1] <- mse(y1, r_ssa$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[1] <- mse(y2, r_ssa$sesonal_cos) |>
  formatC(format = "e", digits = 1)
data$e_err[1] <- mse(y3, r_ssa$e) |>
  formatC(format = "e", digits = 1)
data$all_err[1] <- mse(y1+ y2 + y3,
                     r_ssa$all) |>
  formatC(format = "e", digits = 1)

data$cos_err[2] <- mse(y1, r_ssa_e$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[2] <- mse(y2, r_ssa_e$sesonal_cos) |>
  formatC(format = "e", digits = 1)
data$e_err[2] <- mse(y3, r_ssa_e$e) |>
  formatC(format = "e", digits = 1)
data$all_err[2] <- mse(y1+ y2 + y3,
                     r_ssa_e$sesonal_sin + r_ssa_e$sesonal_cos + r_ssa_e$e
                       ) |>
  formatC(format = "e", digits = 1)


data$cos_err[3] <- mse(y1[1:(n-1)], r_fft_grouped$sesonal_sin) |>
  formatC(format = "e", digits = 1)
data$sin_err[3] <- mse(y2[1:(n-1)], r_fft_grouped$sesonal_cos) |>
  formatC(format = "e", digits = 1)
data$e_err[3] <- mse(y3[1:(n-1)], r_fft_grouped$e) |>
  formatC(format = "e", digits = 1)
data$all_err[3] <- mse((y1 + y2 + y3)[1:(n-1)], 
                       r_fft_grouped$sesonal_sin + r_fft_grouped$sesonal_cos + r_fft_grouped$e) |>
  formatC(format = "e", digits = 1)


data$cos_err[4] <- mse(y1, r_cissa_grouped$sesonal_sin) |> 
  formatC(format = "e", digits = 1)
data$sin_err[4] <- mse(y2, r_cissa_grouped$sesonal_cos) |> 
  formatC(format = "e", digits = 1)
data$e_err[4] <- mse(y3, r_cissa_grouped$e) |>
  formatC(format = "e", digits = 1)
data$all_err[4] <- mse(y1 + y2 + y3, 
                       r_cissa_grouped$sesonal_sin + 
                         r_cissa_grouped$sesonal_cos + 
                         r_cissa_grouped$e
                       ) |>
  formatC(format = "e", digits = 1)

data$cos_err[5] <- mse(y1, r_cissa_grouped_ext$sesonal_sin) |> 
  formatC(format = "e", digits = 1)
data$sin_err[5] <- mse(y2, r_cissa_grouped_ext$sesonal_cos) |> 
  formatC(format = "e", digits = 1)
data$e_err[5] <- mse(y3, r_cissa_grouped_ext$e) |>
  formatC(format = "e", digits = 1)
data$all_err[5] <- mse(y1 + y2 + y3, 
                       r_cissa_grouped_ext$sesonal_sin + 
                         r_cissa_grouped_ext$sesonal_cos +
                          r_cissa_grouped_ext$e
                       ) |>
  formatC(format = "e", digits = 1)

data$cos_err[6] <- mse(y1[1:(n-1)], r_fft_grouped_extended$sesonal_sin) |> 
  formatC(format = "e", digits = 1)
data$sin_err[6] <- mse(y2[1:(n-1)], r_fft_grouped_extended$sesonal_cos) |> 
  formatC(format = "e", digits = 1)
data$e_err[6] <- mse(y3[1:(n-1)], r_fft_grouped_extended$e) |>
  formatC(format = "e", digits = 1)
data$all_err[6] <- mse((y1 + y2 + y3)[1:(n-1)], 
                       r_fft_grouped_extended$sesonal_sin +
                         r_fft_grouped_extended$sesonal_cos +
                         r_fft_grouped_extended$e
                       ) |>
  formatC(format = "e", digits = 1)



table_latex <- xtable(data, caption = "Example Table")

# Шаг 4: Вывод таблицы в LaTeX файл
print(table_latex, include.rownames = FALSE)
% latex table generated in R 4.2.2 by xtable 1.8-4 package
% Tue Mar  4 21:06:56 2025
\begin{table}[ht]
\centering
\begin{tabular}{lllll}
  \hline
Метод & e\_err & sin\_err & cos\_err & all\_err \\ 
  \hline
SSA & 7.3e-05 & 4.2e-06 & 6.2e-05 & 1.1e-27 \\ 
  SSA EOSSA & 1.0e-27 & 2.3e-29 & 9.7e-30 & 9.5e-28 \\ 
  Fourier & 1.2e-01 & 1.9e-02 & 2.2e-02 & 1.0e-01 \\ 
  CiSSA & 7.6e-02 & 4.1e-02 & 1.4e-02 & 1.1e-01 \\ 
  CiSSA extended & 5.8e-04 & 1.3e-02 & 2.0e-03 & 1.4e-02 \\ 
  Fourier extended & 2.7e-03 & 3.1e-04 & 3.1e-03 & 5.9e-03 \\ 
   \hline
\end{tabular}
\caption{Example Table} 
\end{table}

ШУМ

sin cos


data <- list(
  Метод = c("SSA","SSA EOSSA","Fourier", "CiSSA", "CiSSA extended", "Fourier extended"),
  sin_err = list(list(), list(), list(), list(), list(), list()),
  cos_err = list(list(), list(), list(), list(), list(), list()),
  all_err = list(list(), list(), list(), list(), list(), list())
)

for (i in 1:100){
  set.seed(i)
  
  n <- 96*2
  L <- 96
  x <- 0:(n-1)
  y1 <- sin(2*pi/12 * x)
  y2 <- cos(2*pi/3 * x)/2
  y <- y1 + y2 + rnorm(n, 0, 0.1)
  X <- hankel(y, L = L)
  eps <- 1/(n+1)
  
  s_ssa <- ssa(y, L)
  r_ssa <- reconstruct(s_ssa, groups = list(
    F1 = c(1, 2),
    F2 = c(3, 4)
  ))
  # r_ssa <- reconstruct(s_ssa, groups=list(
  #   sesonal_sin = c(1, 2),
  #   sesonal_cos = c(3, 4)
  # ))
  # plot(x[1:(n-1)], r_ssa$F1, type = "l")
  # plot(x[1:(n-1)], r_ssa$F2, type = "l")
  # plot(wcor(s_ssa, groups = 1:10), scales = list(at = c(10, 20, 30)))
  e_ssa <- eossa_new(s_ssa, nested.groups = list(1:4), clust_type = "distance")
  g_sesonal_e <- grouping.auto(e_ssa, base = "eigen",
                         freq.bins = list(
                           sesonal_sin = c(1/12-eps, 1/12+eps),
                           sesonal_cos = c(1/3-eps, 1/3+eps)
                                          ),
                         threshold = 0.5)
  r_ssa_e <- reconstruct(e_ssa, groups=g_sesonal_e)
  # plot(x, r_ssa_e$sesonal_sin)
  # plot(x, r_ssa_e$sesonal_cos)
  
  
  
  r_fft <- reconstruct_fft(x[1:(n-1)], y[1:(n-1)])
  r_fft_grouped <- grouping_cissa(r_fft,
                      groups = list(
                        sesonal_sin = c(1/12-eps, 1/12+eps),
                        sesonal_cos = c(1/3-eps, 1/3+eps)
                      )
                      )$t_series
  
  r_fft_extended <- reconstruct_fft(x[1:(n-1)], y[1:(n-1)], TRUE)
  r_fft_grouped_extended <- grouping_cissa(r_fft_extended,
                      groups = list(
                        sesonal_sin = c(1/12-eps, 1/12+eps),
                        sesonal_cos = c(1/3-eps, 1/3+eps)
                      )
                      )$t_series
  
  # r_fft_grouped$sesonal_sin |> length()
  
  # plot(x, r_fft_grouped$sesonal_sin)
  # plot(x, r_fft_grouped$sesonal_cos)
  # plot(x, r_fft_grouped$residuals)
  
  
  r_cissa <- circulant_SSA(y, L+1)
  r_cissa_grouped <- grouping_cissa(r_cissa,
                      groups = list(
                        sesonal_sin = c(1/12-eps, 1/12+eps),
                        sesonal_cos = c(1/3-eps, 1/3+eps)
                      )
                      )$t_series
  
  
  r_cissa_ext <- circulant_SSA(y, L+1, extend_flag = TRUE)
  r_cissa_grouped_ext <- grouping_cissa(r_cissa_ext,
                      groups = list(
                        sesonal_sin = c(1/12-eps, 1/12+eps),
                        sesonal_cos = c(1/3-eps, 1/3+eps)
                      )
                      )$t_series
  data$cos_err[[1]][[i]] <- 
    min(mse(y1, r_ssa$F1), mse(y1, r_ssa$F2))
  data$sin_err[[1]][[i]] <-
    min(mse(y2, r_ssa$F1), mse(y2, r_ssa$F2))
  data$all_err[[1]][[i]] <-
    min(mse(y1+y2, r_ssa$F1+ r_ssa$F2))
  
  data$cos_err[[2]][[i]] <- mse(y1, r_ssa_e$sesonal_sin)
  data$sin_err[[2]][[i]] <- mse(y2, r_ssa_e$sesonal_cos)
  data$all_err[[2]][[i]] <- mse(y1+ y2,
                                r_ssa_e$sesonal_sin + r_ssa_e$sesonal_cos)
  
  
  data$cos_err[[3]][[i]] <- mse(y1[1:(n-1)], r_fft_grouped$sesonal_sin)
  data$sin_err[[3]][[i]] <- mse(y2[1:(n-1)], r_fft_grouped$sesonal_cos)
  data$all_err[[3]][[i]] <- mse((y1 + y2)[1:(n-1)],
                                r_fft_grouped$sesonal_cos +  r_fft_grouped$sesonal_sin)
  
  
  data$cos_err[[4]][[i]] <- mse(y1, r_cissa_grouped$sesonal_sin)
  data$sin_err[[4]][[i]] <- mse(y2, r_cissa_grouped$sesonal_cos)
  data$all_err[[4]][[i]] <- mse(y1 + y2,
                          r_cissa_grouped$sesonal_sin +  r_cissa_grouped$sesonal_cos
                                )
  
  data$cos_err[[5]][[i]] <- mse(y1, r_cissa_grouped_ext$sesonal_sin)
  data$sin_err[[5]][[i]] <- mse(y2, r_cissa_grouped_ext$sesonal_cos)
  data$all_err[[5]][[i]] <- mse(y1 + y2,
                          r_cissa_grouped_ext$sesonal_sin + r_cissa_grouped_ext$sesonal_cos
                                )
  
  data$cos_err[[6]][[i]] <- mse(y1[1:(n-1)], r_fft_grouped_extended$sesonal_sin)
  data$sin_err[[6]][[i]] <- mse(y2[1:(n-1)], r_fft_grouped_extended$sesonal_cos)
  data$all_err[[6]][[i]] <- mse((y1 + y2)[1:(n-1)],
                          r_fft_grouped_extended$sesonal_sin + r_fft_grouped_extended$sesonal_cos
                                )
}
library(xtable)

# Шаг 2: Создание примера данных
data_prev <- data

data <- data.frame(
  Метод = c("SSA", "SSA EOSSA","Fourier", "CiSSA", "CiSSA extended", "Fourier extended"),
  sin_err = c(0, 0, 0, 0, 0, 0),
  cos_err = c(0, 0, 0, 0, 0, 0),
  all_err = c(0, 0, 0, 0, 0, 0)
)

data$cos_err[1] <- mean(data_prev$cos_err[[1]] |> unlist()) |>
  formatC(format = "e", digits = 1)
data$sin_err[1] <- mean(data_prev$sin_err[[1]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$all_err[1] <- mean(data_prev$all_err[[1]]|> unlist()) |>
  formatC(format = "e", digits = 1)

data$cos_err[2] <- mean(data_prev$cos_err[[2]] |> unlist()) |>
  formatC(format = "e", digits = 1)
data$sin_err[2] <- mean(data_prev$sin_err[[2]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$all_err[2] <- mean(data_prev$all_err[[2]]|> unlist()) |>
  formatC(format = "e", digits = 1)


data$cos_err[3] <- mean(data_prev$cos_err[[3]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$sin_err[3] <- mean(data_prev$sin_err[[3]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$all_err[3] <- mean(data_prev$all_err[[3]]|> unlist()) |>
  formatC(format = "e", digits = 1)


data$cos_err[4] <- mean(data_prev$cos_err[[4]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$sin_err[4] <- mean(data_prev$sin_err[[4]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$all_err[4] <- mean(data_prev$all_err[[4]]|> unlist()) |>
  formatC(format = "e", digits = 1)


data$cos_err[5] <- mean(data_prev$cos_err[[5]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$sin_err[5] <- mean(data_prev$sin_err[[5]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$all_err[5] <- mean(data_prev$all_err[[5]]|> unlist()) |>
  formatC(format = "e", digits = 1)

data$cos_err[6] <- mean(data_prev$cos_err[[6]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$sin_err[6] <- mean(data_prev$sin_err[[6]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$all_err[6] <- mean(data_prev$all_err[[6]]|> unlist()) |>
  formatC(format = "e", digits = 1)
for (i in 1:6){
  for (j in (i):6){
    x <- data_prev$cos_err[[i]] |> unlist()
    y <- data_prev$cos_err[[j]] |> unlist()
    t_test_result <- t.test(x, y, paired = TRUE)
    print(paste("cos, ", data$Метод[i], " ", data$Метод[j], ", p-val = ", t_test_result$p.value))
  }
}
[1] "cos,  SSA   SSA , p-val =  NaN"
[1] "cos,  SSA   SSA EOSSA , p-val =  0.00375920173694349"
[1] "cos,  SSA   Fourier , p-val =  1.51404382822711e-169"
[1] "cos,  SSA   CiSSA , p-val =  3.29860906596866e-111"
[1] "cos,  SSA   CiSSA extended , p-val =  5.64048210410133e-47"
[1] "cos,  SSA   Fourier extended , p-val =  1.01425251456968e-24"
[1] "cos,  SSA EOSSA   SSA EOSSA , p-val =  NaN"
[1] "cos,  SSA EOSSA   Fourier , p-val =  2.25276808232157e-169"
[1] "cos,  SSA EOSSA   CiSSA , p-val =  8.22165658613179e-111"
[1] "cos,  SSA EOSSA   CiSSA extended , p-val =  5.28126497758139e-47"
[1] "cos,  SSA EOSSA   Fourier extended , p-val =  8.88308573812414e-25"
[1] "cos,  Fourier   Fourier , p-val =  NaN"
[1] "cos,  Fourier   CiSSA , p-val =  3.97304209485035e-68"
[1] "cos,  Fourier   CiSSA extended , p-val =  1.60214640844057e-69"
[1] "cos,  Fourier   Fourier extended , p-val =  2.3783103620281e-126"
[1] "cos,  CiSSA   CiSSA , p-val =  NaN"
[1] "cos,  CiSSA   CiSSA extended , p-val =  1.2191415918004e-84"
[1] "cos,  CiSSA   Fourier extended , p-val =  5.29123776807701e-106"
[1] "cos,  CiSSA extended   CiSSA extended , p-val =  NaN"
[1] "cos,  CiSSA extended   Fourier extended , p-val =  1.40973401304321e-38"
[1] "cos,  Fourier extended   Fourier extended , p-val =  NaN"
for (i in 1:6){
  for (j in (i):6){
    x <- data_prev$sin_err[[i]] |> unlist()
    y <- data_prev$sin_err[[j]] |> unlist()
    t_test_result <- t.test(x, y, paired = TRUE)
    print(paste("sin, ", data$Метод[i], " ", data$Метод[j], ", p-val = ", t_test_result$p.value))
  }
}
[1] "sin,  SSA   SSA , p-val =  NaN"
[1] "sin,  SSA   SSA EOSSA , p-val =  0.336775539882117"
[1] "sin,  SSA   Fourier , p-val =  4.76287654518595e-217"
[1] "sin,  SSA   CiSSA , p-val =  3.84407235752248e-144"
[1] "sin,  SSA   CiSSA extended , p-val =  1.78162751656249e-102"
[1] "sin,  SSA   Fourier extended , p-val =  3.00044723408822e-46"
[1] "sin,  SSA EOSSA   SSA EOSSA , p-val =  NaN"
[1] "sin,  SSA EOSSA   Fourier , p-val =  1.40024219747948e-217"
[1] "sin,  SSA EOSSA   CiSSA , p-val =  4.71006927430272e-144"
[1] "sin,  SSA EOSSA   CiSSA extended , p-val =  2.31135766791717e-102"
[1] "sin,  SSA EOSSA   Fourier extended , p-val =  2.82318707677747e-46"
[1] "sin,  Fourier   Fourier , p-val =  NaN"
[1] "sin,  Fourier   CiSSA , p-val =  1.23068528593787e-117"
[1] "sin,  Fourier   CiSSA extended , p-val =  4.3521331389095e-52"
[1] "sin,  Fourier   Fourier extended , p-val =  5.03349389371533e-171"
[1] "sin,  CiSSA   CiSSA , p-val =  NaN"
[1] "sin,  CiSSA   CiSSA extended , p-val =  6.7311046153389e-116"
[1] "sin,  CiSSA   Fourier extended , p-val =  1.54715705776363e-140"
[1] "sin,  CiSSA extended   CiSSA extended , p-val =  NaN"
[1] "sin,  CiSSA extended   Fourier extended , p-val =  9.42243190817026e-100"
[1] "sin,  Fourier extended   Fourier extended , p-val =  NaN"
for (i in 1:6){
  for (j in (i):6){
    x <- data_prev$all_err[[i]] |> unlist()
    y <- data_prev$all_err[[j]] |> unlist()
    t_test_result <- t.test(x, y, paired = TRUE)
    print(paste("all_err, ", data$Метод[i], " ", data$Метод[j], ", p-val = ", t_test_result$p.value))
  }
}
[1] "all_err,  SSA   SSA , p-val =  NaN"
[1] "all_err,  SSA   SSA EOSSA , p-val =  0.652445084718918"
[1] "all_err,  SSA   Fourier , p-val =  3.16479206612653e-215"
[1] "all_err,  SSA   CiSSA , p-val =  2.30409256390872e-148"
[1] "all_err,  SSA   CiSSA extended , p-val =  2.29100216793775e-104"
[1] "all_err,  SSA   Fourier extended , p-val =  4.48213937663307e-49"
[1] "all_err,  SSA EOSSA   SSA EOSSA , p-val =  NaN"
[1] "all_err,  SSA EOSSA   Fourier , p-val =  3.16479206612545e-215"
[1] "all_err,  SSA EOSSA   CiSSA , p-val =  2.30409256390872e-148"
[1] "all_err,  SSA EOSSA   CiSSA extended , p-val =  2.29100216793755e-104"
[1] "all_err,  SSA EOSSA   Fourier extended , p-val =  4.48213937663295e-49"
[1] "all_err,  Fourier   Fourier , p-val =  NaN"
[1] "all_err,  Fourier   CiSSA , p-val =  3.11365252924211e-119"
[1] "all_err,  Fourier   CiSSA extended , p-val =  4.8548720516707e-78"
[1] "all_err,  Fourier   Fourier extended , p-val =  1.70922443458198e-169"
[1] "all_err,  CiSSA   CiSSA , p-val =  NaN"
[1] "all_err,  CiSSA   CiSSA extended , p-val =  1.512849515024e-119"
[1] "all_err,  CiSSA   Fourier extended , p-val =  6.42880469833046e-145"
[1] "all_err,  CiSSA extended   CiSSA extended , p-val =  NaN"
[1] "all_err,  CiSSA extended   Fourier extended , p-val =  6.45006548728807e-101"
[1] "all_err,  Fourier extended   Fourier extended , p-val =  NaN"
table_latex <- xtable(data, caption = "Example Table")

# Шаг 4: Вывод таблицы в LaTeX файл
print(table_latex, include.rownames = FALSE)
% latex table generated in R 4.2.2 by xtable 1.8-4 package
% Tue Mar  4 21:16:32 2025
\begin{table}[ht]
\centering
\begin{tabular}{llll}
  \hline
Метод & sin\_err & cos\_err & all\_err \\ 
  \hline
SSA & 2.9e-04 & 3.1e-04 & 5.9e-04 \\ 
  SSA EOSSA & 2.9e-04 & 3.0e-04 & 5.9e-04 \\ 
  Fourier & 1.8e-02 & 7.6e-03 & 2.6e-02 \\ 
  CiSSA & 4.1e-02 & 1.2e-02 & 5.2e-02 \\ 
  CiSSA extended & 1.4e-02 & 3.0e-03 & 1.7e-02 \\ 
  Fourier extended & 1.2e-03 & 8.4e-04 & 2.0e-03 \\ 
   \hline
\end{tabular}
\caption{Example Table} 
\end{table}
# mean(data_prev$sin_err[[2]] |> unlist()) |> print()
# mean(data_prev$sin_err[[1]] |> unlist()) |> print()

sin cos trend

data <- list(
  Метод = c("SSA", "SSA EOSSA","Fourier", "CiSSA", "CiSSA extended", "Fourier extended"),
  sin_err = list(list(), list(), list(), list(), list(), list()),
  cos_err = list(list(), list(), list(), list(), list(), list()),
  exp_err = list(list(), list(), list(), list(), list(), list()),
  all_err = list(list(), list(), list(), list(), list(), list())
)

for (i in 1:100){
  set.seed(i)
  
  n <- 96*2
  x <- 0:(n-1)
  L <- 96
  y1 <- sin(2*pi/12 * x)
  y2 <- cos(2*pi/3 * x)/2
  y3 <- exp(x/100) + 1
  y <- y1 + y2 + y3 + rnorm(n, 0, 0.1)
  eps <- 1/(n+1)
  
  s_ssa <- ssa(y, L)
  r_ssa <- reconstruct(s_ssa, groups=list(
    e = 1,
    sesonal_sin = c(2, 3),
    sesonal_cos = c(4, 5)
  ))
  
  
  e_ssa <- eossa_new(s_ssa, nested.groups = list(1:7), clust_type = "distance")
  g_sesonal_e <- grouping.auto(e_ssa, base = "eigen",
                         freq.bins = list(
                           e = c(0, 1/12-eps-eps),
                           sesonal_sin = c(1/12-eps, 1/12+eps),
                           sesonal_cos = c(1/3-eps, 1/3+eps)
                                          ),
                         threshold = 0.5)
  r_ssa_e <- reconstruct(e_ssa, groups=g_sesonal_e)
  
  
  
  r_fft <- reconstruct_fft(x[1:(n-1)], y[1:(n-1)])
  r_fft_grouped <- grouping_cissa(r_fft,
                      groups = list(
                        e = c(0, 1/12-eps-eps),
                        sesonal_sin = c(1/12-eps, 1/12+eps),
                        sesonal_cos = c(1/3-eps, 1/3+eps)
                      )
                      )$t_series
  
  r_fft_extended <- reconstruct_fft(x[1:(n-1)], y[1:(n-1)], TRUE)
  r_fft_grouped_extended <- grouping_cissa(r_fft_extended,
                      groups = list(
                        e = c(0, 1/12-eps-eps),
                        sesonal_sin = c(1/12-eps, 1/12+eps),
                        sesonal_cos = c(1/3-eps, 1/3+eps)
                      )
                      )$t_series
  
  
  r_cissa <- circulant_SSA(y, L+1)
  r_cissa_grouped <- grouping_cissa(r_cissa,
                      groups = list(
                        e = c(0, 1/12-eps-eps),
                        sesonal_sin = c(1/12-eps, 1/12+eps),
                        sesonal_cos = c(1/3-eps, 1/3+eps)
                      )
                      )$t_series
  
  
  r_cissa_ext <- circulant_SSA(y, L+1, extend_flag = TRUE)
  r_cissa_grouped_ext <- grouping_cissa(r_cissa_ext,
                      groups = list(
                        e = c(0, 1/12-eps-eps),
                        sesonal_sin = c(1/12-eps, 1/12+eps),
                        sesonal_cos = c(1/3-eps, 1/3+eps)
                      )
                      )$t_series
  
  
  
  data$cos_err[[1]][[i]] <- mse(y1, r_ssa$sesonal_sin)
  data$sin_err[[1]][[i]] <- mse(y2, r_ssa$sesonal_cos)
  data$exp_err[[1]][[i]] <- mse(y3, r_ssa$e)
  data$all_err[[1]][[i]] <- mse(y1 + y2 + y3,
                                r_ssa$sesonal_sin+
                                  r_ssa$sesonal_cos +
                                  r_ssa$e
                                )
  
  data$cos_err[[2]][[i]] <- mse(y1, r_ssa_e$sesonal_sin)
  data$sin_err[[2]][[i]] <- mse(y2, r_ssa_e$sesonal_cos)
  data$exp_err[[2]][[i]] <- mse(y3, r_ssa_e$e)
  data$all_err[[2]][[i]] <- mse(y1 + y2 + y3,
                                r_ssa_e$sesonal_sin+ 
                                  r_ssa_e$sesonal_cos + 
                                  r_ssa_e$e
                                )
  
  
  # print(data$sin_err[[2]][[i]])
  
  
  data$cos_err[[3]][[i]] <- mse(y1[1:(n-1)], r_fft_grouped$sesonal_sin)
  data$sin_err[[3]][[i]] <- mse(y2[1:(n-1)], r_fft_grouped$sesonal_cos)
  data$exp_err[[3]][[i]] <- mse(y3[1:(n-1)], r_fft_grouped$e)
  data$all_err[[3]][[i]] <- mse((y1 + y2 + y3)[1:(n-1)],
                                r_fft_grouped$sesonal_sin +
                                  r_fft_grouped$sesonal_cos +
                                  r_fft_grouped$e
                                )
  
  
  data$cos_err[[4]][[i]] <- mse(y1, r_cissa_grouped$sesonal_sin)
  data$sin_err[[4]][[i]] <- mse(y2, r_cissa_grouped$sesonal_cos)
  data$exp_err[[4]][[i]] <- mse(y3, r_cissa_grouped$e)
  data$all_err[[4]][[i]] <- mse(y1 + y2 + y3,
                                r_cissa_grouped$sesonal_sin +
                                  r_cissa_grouped$sesonal_cos +
                                  r_cissa_grouped$e
                                )
  
  
  data$cos_err[[5]][[i]] <- mse(y1, r_cissa_grouped_ext$sesonal_sin)
  data$sin_err[[5]][[i]] <- mse(y2, r_cissa_grouped_ext$sesonal_cos)
  data$exp_err[[5]][[i]] <- mse(y3, r_cissa_grouped_ext$e)
  data$all_err[[5]][[i]] <- mse(y1 + y2 + y3,
                                r_cissa_grouped_ext$sesonal_sin + 
                                  r_cissa_grouped_ext$sesonal_cos +
                                  r_cissa_grouped_ext$e
                                )
  
  data$cos_err[[6]][[i]] <- mse(y1[1:(n-1)], r_fft_grouped_extended$sesonal_sin)
  data$sin_err[[6]][[i]] <- mse(y2[1:(n-1)], r_fft_grouped_extended$sesonal_cos)
  data$exp_err[[6]][[i]] <- mse(y3[1:(n-1)], r_fft_grouped_extended$e)
  data$all_err[[6]][[i]] <- mse((y1 + y2 + y3)[1:(n-1)],
                                r_fft_grouped_extended$sesonal_sin +
                                  r_fft_grouped_extended$sesonal_cos +
                                  r_fft_grouped_extended$e
                                )
}
library(xtable)
# data$sin_err[[2]]
# Шаг 2: Создание примера данных
data_prev <- data
data <- data.frame(
  Метод = c("SSA", "SSA EOSSA","Fourier", "CiSSA", "CiSSA extended", "Fourier extended"),
  exp_err = c(0, 0, 0, 0, 0, 0),
  sin_err = c(0, 0, 0, 0, 0, 0),
  cos_err = c(0, 0, 0, 0, 0, 0),
  all_err = c(0, 0, 0, 0, 0, 0)
)

data$cos_err[1] <- mean(data_prev$cos_err[[1]] |> unlist()) |>
  formatC(format = "e", digits = 1)
data$sin_err[1] <- mean(data_prev$sin_err[[1]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$exp_err[1] <- mean(data_prev$exp_err[[1]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$all_err[1] <- mean(data_prev$all_err[[1]]|> unlist()) |>
  formatC(format = "e", digits = 1)


data$cos_err[2] <- mean(data_prev$cos_err[[2]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$sin_err[2] <- mean(data_prev$sin_err[[2]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$exp_err[2] <- mean(data_prev$exp_err[[2]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$all_err[2] <- mean(data_prev$all_err[[2]]|> unlist()) |>
  formatC(format = "e", digits = 1)


data$cos_err[3] <- mean(data_prev$cos_err[[3]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$sin_err[3] <- mean(data_prev$sin_err[[3]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$exp_err[3] <- mean(data_prev$exp_err[[3]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$all_err[3] <- mean(data_prev$all_err[[3]]|> unlist()) |>
  formatC(format = "e", digits = 1)


data$cos_err[4] <- mean(data_prev$cos_err[[4]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$sin_err[4] <- mean(data_prev$sin_err[[4]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$exp_err[4] <- mean(data_prev$exp_err[[4]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$all_err[4] <- mean(data_prev$all_err[[4]]|> unlist()) |>
  formatC(format = "e", digits = 1)

data$cos_err[5] <- mean(data_prev$cos_err[[5]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$sin_err[5] <- mean(data_prev$sin_err[[5]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$exp_err[5] <- mean(data_prev$exp_err[[5]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$all_err[5] <- mean(data_prev$all_err[[5]]|> unlist()) |>
  formatC(format = "e", digits = 1)

data$cos_err[6] <- mean(data_prev$cos_err[[6]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$sin_err[6] <- mean(data_prev$sin_err[[6]]|> unlist()) |> 
  formatC(format = "e", digits = 1)
data$exp_err[6] <- mean(data_prev$exp_err[[6]]|> unlist()) |>
  formatC(format = "e", digits = 1)
data$all_err[6] <- mean(data_prev$all_err[[6]]|> unlist()) |>
  formatC(format = "e", digits = 1)
for (i in 1:6){
  for (j in (i):6){
    x <- data_prev$cos_err[[i]] |> unlist()
    y <- data_prev$cos_err[[j]] |> unlist()
    t_test_result <- t.test(x, y, paired = TRUE)
    if (!is.na(t_test_result$p.value) & t_test_result$p.value > 0.05){
      print(paste("cos, ", data$Метод[i], " ",
                  data$Метод[j], ", p-val = ", t_test_result$p.value))
      }
  }
}

for (i in 1:6){
  for (j in (i):6){
    x <- data_prev$sin_err[[i]] |> unlist()
    y <- data_prev$sin_err[[j]] |> unlist()
    t_test_result <- t.test(x, y, paired = TRUE)
    if (!is.na(t_test_result$p.value) & t_test_result$p.value > 0.05){
      print(paste("sin, ", data$Метод[i], " ", data$Метод[j], ", p-val = ", t_test_result$p.value))
      }
  }
}
[1] "sin,  SSA   SSA EOSSA , p-val =  0.0716417308563743"
for (i in 1:6){
  for (j in (i):6){
    x <- data_prev$exp_err[[i]] |> unlist()
    y <- data_prev$exp_err[[j]] |> unlist()
    t_test_result <- t.test(x, y, paired = TRUE)
    if (!is.na(t_test_result$p.value) & t_test_result$p.value > 0.05){
      print(paste("exp, ", data$Метод[i], " ", data$Метод[j], ", p-val = ", t_test_result$p.value))}
  }
}

for (i in 1:6){
  for (j in (i):6){
    x <- data_prev$all_err[[i]] |> unlist()
    y <- data_prev$all_err[[j]] |> unlist()
    t_test_result <- t.test(x, y, paired = TRUE)
    if (!is.na(t_test_result$p.value) & t_test_result$p.value > 0.05){
      print(paste("all_err, ", data$Метод[i], " ", data$Метод[j], ", p-val = ", t_test_result$p.value))
      }
  }
}


table_latex <- xtable(data, caption = "Example Table")

# Шаг 4: Вывод таблицы в LaTeX файл
print(table_latex, include.rownames = FALSE)
% latex table generated in R 4.2.2 by xtable 1.8-4 package
% Tue Mar  4 21:25:11 2025
\begin{table}[ht]
\centering
\begin{tabular}{lllll}
  \hline
Метод & exp\_err & sin\_err & cos\_err & all\_err \\ 
  \hline
SSA & 5.5e-03 & 2.9e-04 & 3.7e-04 & 5.3e-03 \\ 
  SSA EOSSA & 9.3e-04 & 2.9e-04 & 3.1e-04 & 1.5e-03 \\ 
  Fourier & 1.2e-01 & 1.9e-02 & 2.2e-02 & 1.0e-01 \\ 
  CiSSA & 7.7e-02 & 4.1e-02 & 1.4e-02 & 1.1e-01 \\ 
  CiSSA extended & 2.7e-03 & 1.4e-02 & 3.3e-03 & 1.7e-02 \\ 
  Fourier extended & 4.7e-03 & 8.6e-04 & 3.0e-03 & 7.8e-03 \\ 
   \hline
\end{tabular}
\caption{Example Table} 
\end{table}
LS0tDQp0aXRsZTogIkNpcmN1bGFudCBTU0EiDQphdXRob3I6ICLQn9C+0LPRgNC10LHQvdC40LrQvtCyINCd0LjQutC+0LvQsNC5Ig0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KYGBge3J9DQp4IDwtIDE6MTAwDQp3IDwtIDEvMjANCnNpbigyKnBpKncgKiB4ICsgMS8yKSArIGNvcygyKnBpKncqIHggKyAxMCozLjM0MTIpIHw+IHBsb3QoKQ0KDQoNCg0KYGBgDQoNCiMjINCS0YHQv9C+0LzQvtCz0LDRgtC10LvRjNC90YvQtSDRhNGD0L3QutGG0LjQuA0KDQpgYGB7cn0NCmxpYnJhcnkoUnNzYSkNCmxpYnJhcnkoc2lnbmFsKQ0KbGlicmFyeShnc2lnbmFsKQ0Kc291cmNlKCJlb3NzYV9uZXcuUiIpDQoNCg0KZGZ0bXR4IDwtIGZ1bmN0aW9uKG4pIHsNCiAgeSA8LSBzdGF0czo6bXZmZnQoZGlhZygxLCBuKSkNCiAgeQ0KfQ0KDQpkaWFnX2F2ZXJhZ2luZyA8LSBmdW5jdGlvbihBKXsNCiAgQiA8LSBBW25yb3coQSk6MSwgXSB8PiBSZSgpDQogIGxhcHBseShzcGxpdChCLCAtKHJvdyhCKSAtIGNvbChCKSkgKSwgbWVhbikgfD4gYXMubnVtZXJpYygpDQp9DQoNCnNoaWZ0X3ZlY3RvciA8LSBmdW5jdGlvbih2ZWMpIHsNCiAgbGFzdF9lbGVtZW50IDwtIHRhaWwodmVjLCAxKQ0KICB2ZWMgPC0gdmVjWy1sZW5ndGgodmVjKV0NCiAgc2hpZnRlZF92ZWMgPC0gYyhsYXN0X2VsZW1lbnQsIHZlYykNCiAgcmV0dXJuKHNoaWZ0ZWRfdmVjKQ0KfQ0KDQpleHRlbmQgPC0gZnVuY3Rpb24oeCwgSCl7DQogICMg0JLRi9GH0LjRgdC70LXQvdC40LUg0LrQvtGN0YTRhNC40YbQuNC10L3RgtC+0LIgQVIg0LzQvtC00LXQu9C4INC00LvRjyDQtNC40YTRhNC10YDQtdC90YbQuNGA0L7QstCw0L3QvdC+0LPQviDRgNGP0LTQsA0KICBOIDwtIGxlbmd0aCh4KQ0KICBwIDwtIGZsb29yKE4gLyAzKQ0KICBkeCA8LSBkaWZmKHgpDQogICMgQSA8LSBhcihkeCwgb3JkZXIubWF4ID0gcCwgbWV0aG9kID0gInl1bGUtd2Fsa2VyIikkYXINCiAgQSA8LSBhcnl1bGUoZHgsIHApJGENCiAgDQogICMg0J/RgNCw0LLQvtC1INGA0LDRgdGI0LjRgNC10L3QuNC1DQogIHkgPC0geA0KICBkeSA8LSBkaWZmKHkpDQogIGVyIDwtIHNpZ25hbDo6ZmlsdGVyKEEsIDEsIGR5KQ0KICBkeSA8LSBzaWduYWw6OmZpbHRlcigxLCBBLCBjKGVyLCByZXAoMCwgSCkpKQ0KICB5IDwtIHlbMV0gKyBjKDAsIGN1bXN1bShkeSkpDQogIA0KICAjINCb0LXQstC+0LUg0YDQsNGB0YjQuNGA0LXQvdC40LUNCiAgeSA8LSByZXYoeSkNCiAgZHkgPC0gZGlmZih5KQ0KICBlciA8LSBzaWduYWw6OmZpbHRlcihBLDEsZHkpDQogIGR5IDwtIHNpZ25hbDo6ZmlsdGVyKDEsQSxjKGVyLCByZXAoMCwgSCkpKQ0KICB5IDwtIHlbMV0gKyBjKDAsIGN1bXN1bShkeSkpDQogIA0KICAjINCg0LDRgdGI0LjRgNC10L3QvdGL0Lkg0YDRj9C0DQogIHhlIDwtIHJldih5KQ0KICANCiAgIyDQktGL0LLQvtC0INGA0LXQt9GD0LvRjNGC0LDRgtC+0LINCiAgeGUgDQp9DQpgYGANCg0KIyMgQ2lTU0ENCg0K0J/QvtC00LDRkdGC0YHRjyDQvdCwINCy0YXQvtC0INCy0YDQtdC80LXQvdC90L7QuSDRgNGP0LQsINC00LvQuNC90LAg0L7QutC90LAgKNC10YHQu9C4INC10ZEg0L3QtdGCLCDRgtC+INC+0L3QsCDRgNCw0LLQvdCwINC00LvQuNC90LUg0YDRj9C00LAgKyAxINC/0L7Qv9C+0LvQsNC8KSDQuCDQuNC90YTQvtGA0LzQsNGG0LjRjyDQviDRgtC+0LwsINC90YPQttC90L4g0LvQuCDRgNCw0YHRiNC40YDQuNGC0Ywg0YDRj9C0LiDQoNCw0YHRiNC40YDRj9GC0Ywg0YDRj9C0INGB0YLQvtC40YIg0L/RgNC4INGB0YLQvtGF0LDRgdGC0LjRh9C10YHQutC+0Lwg0YLRgNC10L3QtNC1IChBdXRvcmVncmVzc2l2ZSBleHRlbnNpb24gKGRlZmF1bHQpLiBJdCBpcyBpbmRpY2F0ZWQgZm9yIHN0YXRpb25hcnkgYW5kIHN0b2NoYXN0aWMgdHJlbmQgdGltZSBzZXJpZXMgYXMgd2VsbCkuINCg0LXQsNC70LjQt9C+0LLQsNC90L4g0YLQvtC70YzQutC+IEF1dG9yZWdyZXNzaXZlIGV4dGVuc2lvbi4NCg0KXA0K0J3QsCDQstGL0YXQvtC00LUg0YHQv9C40YHQvtC6INCy0YvQtNCw0ZHRgtGB0Y8g0YHQv9C40YHQvtC6IGxpc3QodF9zZXJpZXMsIGltcG9ydGFuY2UpLlwNCnRfc2VyaWVzIOKAlCDQvNCw0YLRgNC40YbQsCwg0L/QviDRgdGC0L7Qu9Cx0YbQsNC8INC60L7RgtC+0YDQvtC5INGA0LDRgdC/0L7Qu9Cw0LPQsNGO0YLRgdGPINCy0YDQtdC80LXQvdC90YvQtSDRgNGP0LTRiywg0L7RgtCy0LXRh9Cw0Y7RidC40LUg0LfQsCDRh9Cw0YHRgtC+0YLRiyAoaS0xKS9MLCDQs9C00LUgaSDigJQg0L3QvtC80LXRgCDRgdGC0L7Qu9Cx0YbQsCwgTCDigJQg0LTQu9C40L3QsCDQvtC60L3QsC5cDQppbXBvcnRhbmNlIOKAlCDQstC10LrRgtC+0YAsINC+0YLQstC10YfQsNGO0YnQuNC5INC30LAg0LfQvdCw0YfQuNC80L7RgdGC0YwgaS3QvtCz0L4g0LLRgNC10LzQtdC90L3QvtCz0L4g0YDRj9C00LAg0LIg0YDQsNC30LvQvtC70LbQtdC90LjQuC4g0KfQtdC8INCx0L7Qu9GM0YjQtSDQt9C90LDRh9C10L3QuNC1LCDRgtC10Lwg0LHQvtC70YzRiNC40Lkg0LLQutC70LDQtCDQstC90ZHRgSBpLdGC0YvQuSDQstGA0LXQvNC10L3QvdC+0Lkg0YDRj9C0Lg0KDQpgYGB7cn0NCmNpcmN1bGFudF9TU0EgPC0gZnVuY3Rpb24odHMsIEwgPSBOVUxMLCBleHRlbmRfZmxhZyA9IEZBTFNFKXsNCiAgdGltZV9zZXJpZXMgPC0gdHMNCiAgIyBDb25zdHJ1Y3QgdHJhamVjdG9yeSBtYXRyaXgNCiAgTiA8LSBsZW5ndGgodGltZV9zZXJpZXMpDQogIGlmIChpcy5udWxsKEwpKXsNCiAgICBMIDwtIChOICsgMSklLyUyDQogIH0NCiAgIyDQn9GA0L7QstC10YDQutCwINC90LAg0YDQsNGB0YjQuNGA0LXQvdC40Y8g0YDRj9C00LANCiAgaWYgKGV4dGVuZF9mbGFnID09IEZBTFNFKXsNCiAgICBIIDwtIDANCiAgICB0aW1lX3NlcmllcyA8LSB0cw0KICB9DQogIGVsc2V7DQogICAgSCA8LSBMDQogICAgdGltZV9zZXJpZXMgPC0gZXh0ZW5kKHRzLCBIKQ0KICB9DQogIA0KICBYIDwtIGhhbmtlbCh0aW1lX3NlcmllcywgTCkNCiAgDQogICMgTnVtYmVyIG9mIHN5bW1ldHJpYyBmcmVxdWVuY3kgcGFpcnMgYXJvdW5kIDEvMg0KICBpZiAoTCAlJSAyKSB7DQogICAgbmYyIDwtIChMICsgMSkgLyAyIC0gMQ0KICB9IGVsc2Ugew0KICAgIG5mMiA8LSBMIC8gMiAtIDENCiAgfQ0KICANCiAgIyBOdW1iZXIgb2YgZnJlcXVlbmNpZXMgPD0gMS8yDQogIG5mdCA8LSBuZjIgKyBhYnMoKEwgJSUgMikgLSAyKQ0KICANCiAgIyBEZWNvbXBvc2l0aW9uDQogICMgRXN0aW1hdGUgYXV0b2NvdmFyaWFuY2UgICAgIE9LDQogIGF1dG9jb3YgPC0gbnVtZXJpYyhMKQ0KICBmb3IgKG0gaW4gMDooTC0xKSl7DQogICAgYXV0b2NvdltbbSsxXV0gPC0gc3VtKHRpbWVfc2VyaWVzWzE6KE4tbSldICogdGltZV9zZXJpZXNbKDErbSk6Tl0pIC8gKE4tbSkNCiAgfQ0KICANCiAgIyBGaXJzdCByb3cgb2YgY2lyY3VsYW50IG1hdHJpeA0KICBjaXJjX2ZpcnN0X3JvdyA8LSBudW1lcmljKEwpDQogIGZvciAobSBpbiAwOihMLTEpKXsNCiAgICBjaXJjX2ZpcnN0X3Jvd1tbbSsxXV0gPC0gKEwtbSkvTCAqIGF1dG9jb3ZbW20rMV1dICsgKG0pL0wgKiBhdXRvY292W1tMLW1dXQ0KICB9DQogIA0KICAjIEJ1aWxkIGNpcmN1bGFudCBtYXRyaXgNCiAgU19DIDwtIG1hdHJpeChjaXJjX2ZpcnN0X3JvdywgbnJvdyA9IDEpDQogIHNoaWZ0ZWRfdmVjdG9yIDwtIGNpcmNfZmlyc3Rfcm93DQogIGZvciAoaSBpbiAyOihMKSkgew0KICAgIHNoaWZ0ZWRfdmVjdG9yIDwtIHNoaWZ0X3ZlY3RvcihzaGlmdGVkX3ZlY3RvcikNCiAgICAjIFNfQyA8LSByYmluZChTX0MsIGFzLnZlY3RvcihzaGlmdGVkX3ZlY3RvcikpDQogICAgU19DIDwtIHJiaW5kKGFzLnZlY3RvcihzaGlmdGVkX3ZlY3RvciksIFNfQykNCiAgfQ0KICANCiAgIyBFaWdlbnZlY3RvcnMgb2YgY2lyY3VsYW50IG1hdHJpeCAodW5pdGFyeSBiYXNlKQ0KICBVIDwtIGRmdG10eChMKS9zcXJ0KEwpDQogIA0KICAjIFJlYWwgZWlnZW52ZWN0b3JzIChvcnRob25vcm1hbCBiYXNlKQ0KICBVWywgMV0gPC0gUmUoVVssIDFdKQ0KICBmb3IgKGsgaW4gMTpuZjIpIHsNCiAgICB1X2sgPC0gVVssIGsgKyAxXQ0KICAgIFVbLCBrICsgMV0gPC0gc3FydCgyKSAqIFJlKHVfaykNCiAgICBVWywgTCArIDIgLSAoayArIDEpXSA8LSBzcXJ0KDIpICogSW0odV9rKQ0KICB9DQogIGlmIChMICUlIDIgIT0gMCkgew0KICAgIFVbLCBuZnRdIDwtIFJlKFVbLCBuZnRdKQ0KICB9DQogIA0KICAjIEVpZ2VudmFsdWVzIG9mIGNpcmN1bGFudCBtYXRyaXg6IGVzdGltYXRlZCBwb3dlciBzcGVjdHJhbCBkZW5zaXR5DQogIHBzZCA8LSBhYnMoZGlhZyh0KFUpICUqJSBTX0MgJSolIFUpKQ0KICANCiAgIyBQcmluY2lwYWwgY29tcG9uZW50cw0KICBXIDwtIHQoVSkgJSolIFgNCiAgIyBSZWNvbnN0cnVjdGlvbg0KICAjIEVsZW1lbnRhcnkgcmVjb25zdHJ1Y3RlZCBzZXJpZXMNCiAgUiA8LSBtYXRyaXgoMCwgbnJvdyA9IE4rMipILCBuY29sID0gTCkNCiAgZm9yIChrIGluIDE6TCkgew0KICAgIFJbLCBrXSA8LSBVWyAsa10gJSolIHQoV1trLCBdKSB8PiBkaWFnX2F2ZXJhZ2luZygpDQogIH0NCiAgDQogICMgR3JvdXBpbmcgYnkgZnJlcXVlbmN5DQogICMgRWxlbWVudGFyeSByZWNvbnN0cnVjdGVkIHNlcmllcyBieSBmcmVxdWVuY3kNCiAgWiA8LSBtYXRyaXgoMCwgbnJvdyA9IE4rMipILCBuY29sID0gbmZ0KQ0KICBaWywgMV0gPC0gUlssIDFdDQogICMgSW1wb3J0YW5jZSBvZiBjb21wb25lbnQNCiAgaW1wIDwtIG51bWVyaWMobmZ0KQ0KICBsYW1iZGFfc20gPC0gc3VtKHBzZCkNCiAgaW1wWzFdIDwtIHBzZFsxXS9sYW1iZGFfc20NCiAgZm9yIChrIGluIDE6bmYyKSB7DQogICAgWlssIGsgKyAxXSA8LSBSWywgayArIDFdICsgUlssIEwgKyAyIC0gKGsgKyAxKV0NCiAgICBpbXBbaysxXSA8LSAocHNkW2srMV0gKyBwc2RbIEwgKyAyIC0gKGsgKyAxKV0pL2xhbWJkYV9zbQ0KICB9DQogIGlmIChMICUlIDIgIT0gMCkgew0KICAgIFpbLCBuZnRdIDwtIFJbLCBuZnRdDQogICAgaW1wW25mdF0gPC0gcHNkW25mdF0gLyBsYW1iZGFfc20NCiAgfQ0KICANCiAgbGlzdCh0X3NlcmllcyA9IFpbKEgrMSk6KE4rSCksXSwNCiAgICAgICBpbXBvcnRhbmNlID0gaW1wLA0KICAgICAgIGZyZXEgPSAoMDoobGVuZ3RoKGltcCkgLTEpKS9MDQogICAgICAgKQ0KfQ0KYGBgDQoNCmBgYHtyfQ0KIyBncm91cHMgLSBsaXN0IG9mIGZyZXF1ZW5jaWVzDQpncm91cGluZ19jaXNzYSA8LSBmdW5jdGlvbihjaXNzYV9yZXMsIGdyb3Vwcyl7DQogIGZyZXEgPC0gY2lzc2FfcmVzJGZyZXENCiAgdF9zZXJpZXMgPC0gY2lzc2FfcmVzJHRfc2VyaWVzDQogIA0KICANCiAgcmVzaWR1YWxzIDwtIDANCiAgcmVzdWx0IDwtIHNldE5hbWVzKGFzLmxpc3QocmVwKDAsIGxlbmd0aChncm91cHMpKSksIG5hbWVzKGdyb3VwcykpDQogIHJlc3VsdF9mcmVxcyA8LSBsaXN0KCkNCiAgZm9yIChpIGluIDE6bGVuZ3RoKGNpc3NhX3JlcyRmcmVxKSl7DQogICAgZmxhZyA8LSBGQUxTRQ0KICAgIGZvciAobmFtZSBpbiBuYW1lcyhncm91cHMpKXsNCiAgICAgIGlmIChncm91cHNbW25hbWVdXVsxXSA8PSBmcmVxW2ldICYgZnJlcVtpXSA8PSBncm91cHNbW25hbWVdXVsyXSl7DQogICAgICAgIGZsYWcgPC0gVFJVRQ0KICAgICAgICByZXN1bHRbW25hbWVdXSA8LSByZXN1bHRbW25hbWVdXSArIHRfc2VyaWVzWywgaV0NCiAgICAgICAgcmVzdWx0X2ZyZXFzW1tuYW1lXV0gPC0gYyhyZXN1bHRfZnJlcXNbW25hbWVdXSwgZnJlcVtpXSkNCiAgICAgIH0NCiAgICB9DQogICAgDQogICAgaWYgKGZsYWcgPT0gRkFMU0Upew0KICAgICAgcmVzaWR1YWxzIDwtIHJlc2lkdWFscyArIHRfc2VyaWVzWywgaV0NCiAgICB9DQogIH0NCiAgDQogIHJlc3VsdFtbInJlc2lkdWFscyJdXSA8LSByZXNpZHVhbHMNCiAgDQogIHJldHVybigNCiAgICBsaXN0KA0KICAgICAgdF9zZXJpZXMgPSByZXN1bHQsDQogICAgICBmcmVxc19ieV9ncm91cCA9IHJlc3VsdF9mcmVxcw0KICAgICkNCiAgKQ0KICByZXN1bHQNCn0NCmBgYA0KDQpgYGB7cn0NCmdlbmVyYXRlX3RzIDwtIGZ1bmN0aW9uKGZ1bmMsIG49MWUzLCAuLi4pew0KICAxOm4gfD4gZnVuYyguLi4pIHw+IHRzKCkNCn0NCg0KZl9jb3MgPC0gZnVuY3Rpb24oeCwgQSA9IDEsIG9tZWdhID0gMS80LCBwaGkgPSAwKXsNCiAgZl9leHBfbW9kX2hhcm1fc2VyaWVzKHgsIEEsIGFscGhhID0gMCwgb21lZ2EgPSBvbWVnYSwgcGhpID0gcGhpKQ0KfQ0KDQpmX3NpbiA8LSBmdW5jdGlvbih4LCBBID0gMSwgb21lZ2EgPSAxLzQsIHBoaSA9IDMqcGkvMil7DQogIGZfZXhwX21vZF9oYXJtX3Nlcmllcyh4LCBBLCBhbHBoYSA9IDAsIG9tZWdhID0gb21lZ2EsIHBoaSA9IHBoaSkNCn0NCg0KZl9leHAgPC0gZnVuY3Rpb24oeCwgQSA9IDEsIGFscGhhID0gMSl7DQogIEEgKiBleHAoYWxwaGEgKiB4KQ0KfQ0KDQpmX2V4cF9jb3MgPC0gZnVuY3Rpb24oeCwgQSA9IDEsIGFscGhhID0gMSwgb21lZ2EgPSAxLzQsIHBoaSA9IDApew0KICBmX2V4cF9tb2RfaGFybV9zZXJpZXMoeCwgQSwgYWxwaGEsIG9tZWdhLCBwaGkpDQp9DQoNCmZfY29uc3QgPC0gZnVuY3Rpb24oeCwgQyA9IDApew0KICByZXAoQywgbGVuZ3RoKHgpKQ0KfQ0KDQpmX2V4cF9tb2RfaGFybV9zZXJpZXMgPC0gZnVuY3Rpb24oeCwgQSA9IDEsIGFscGhhID0gMSwgb21lZ2EgPSAxLzQsIHBoaSA9IDApew0KICBBKmV4cChhbHBoYSp4KSpjb3MoMipwaSpvbWVnYSp4ICsgcGhpKQ0KfQ0KDQpmX2xpbmVhciA8LSBmdW5jdGlvbih4LCBhID0gMSwgYiA9IDApew0KICBhKnggKyBiDQp9DQptc2UgPC0gZnVuY3Rpb24oZl90cnVlLCBmX3JlY29uc3RydWN0ZWQpew0KICAgbWVhbigoZl90cnVlIC0gZl9yZWNvbnN0cnVjdGVkKV4yKSANCn0NCmBgYA0KDQojIyMjINCe0YjQuNCx0LrQsCDQv9GA0LggTHcgaW4gTiwgS3cgbm90IGluIE4NCg0KYGBge3J9DQpuIDwtIDk2KjIrNQ0KTCA8LSA5Ng0KZXBzIDwtIDEvOTcNCmZfc3VtIDwtIGZ1bmN0aW9uKHgpew0KICBmX2NvbnN0KHgsIEMgPSAxKSArIGZfY29zKHgsIG9tZWdhID0gMS8xMikgDQp9DQoNCg0KZl9jb25zdCB8PiBnZW5lcmF0ZV90cyhuLCBDID0gMSkgfD4NCiAgcGxvdChjb2wgPSAiZ3JlZW4iLCB5bGltID0gYygtMSwgMiksIHlsYWIgPSAiZl9uIikNCmZfY29zIHw+DQogIGdlbmVyYXRlX3RzKG4sIG9tZWdhID0gMS8xMikgfD4NCiAgbGluZXMoY29sPSJncmVlbiIpDQpmX3N1bSB8PiBnZW5lcmF0ZV90cyhuKSB8PiBsaW5lcyhsd2QgPSAzLCBjb2w9J3JlZCcpDQpmX24gPC0gZl9zdW0oMTpuKQ0KDQoNCg0KYyA8LSBjaXJjdWxhbnRfU1NBKGZfbiwgTCA9IDk2LCBleHRlbmRfZmxhZyA9IEZBTFNFKQ0KciA8LSBncm91cGluZ19jaXNzYShjLA0KICAgICAgICAgICAgICAgZ3JvdXBzID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgdHJlbmQgPSBjKDAsIGVwcyksDQogICAgICAgICAgICAgICAgIHNlc29uYWwgPSBjKDEvMTItZXBzLCAxLzEyICsgZXBzKQ0KICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgKSR0X3Nlcmllcw0KDQpmX0MgPC0gZl9jb25zdCB8PiBnZW5lcmF0ZV90cyhuLCBDID0gMSkNCmZfYyA8LSBmX2NvcyB8PiBnZW5lcmF0ZV90cyhuLCBvbWVnYSA9IDEvMTIpDQpwcmludCgi0J7RiNC40LHQutC4INC/0YDQuCBDaVNTQSIpDQpwcmludChwYXN0ZSgi0J7RiNC40LHQutCwINC/0YDQuCDQstGL0YfQuNGB0LvQtdC90LjQuCBDID0gMTogIiwgbXNlKGZfQywgciR0cmVuZCkgfD4gZm9ybWF0KHNjaWVudGlmaWMgPSBUUlVFLCBkaWdpdHMgPSAyKSApKQ0KcHJpbnQocGFzdGUoItCe0YjQuNCx0LrQsCDQv9GA0Lgg0LLRi9GH0LjRgdC70LXQvdC40LggY29zKHBpLzEyKTogIiwgbXNlKGZfYywgciRzZXNvbmFsKSB8PiBmb3JtYXQoc2NpZW50aWZpYyA9IFRSVUUsIGRpZ2l0cyA9IDIpICkpDQoNCmxpbmVzKDE6biwgciR0cmVuZCwgY29sPSJibHVlIikNCmxpbmVzKDE6biwgciRzZXNvbmFsLCBjb2w9ImJsdWUiKQ0KDQpmX2NvbnN0IHw+IGdlbmVyYXRlX3RzKG4sIEMgPSAxKSB8Pg0KICBwbG90KGNvbCA9ICJncmVlbiIsIHlsaW0gPSBjKC0xLCAyKSwgeWxhYiA9ICJmX24iKQ0KZl9jb3MgfD4NCiAgZ2VuZXJhdGVfdHMobiwgb21lZ2EgPSAxLzEyKSB8Pg0KICBsaW5lcyhjb2w9ImdyZWVuIikNCmZfc3VtIHw+IGdlbmVyYXRlX3RzKG4pIHw+IGxpbmVzKGx3ZCA9IDMsIGNvbD0ncmVkJykNCmZfbiA8LSBmX3N1bSgxOm4pDQoNCnMgPC0gc3NhKGZfbiwgTCA9IDk2KQ0KciA8LSByZWNvbnN0cnVjdChzLCBncm91cHM9bGlzdCgNCiAgdHJlbmQgPSAxLA0KICBzZXNvbmFsID0gMjozDQopKQ0KDQoNCnByaW50KCLQntGI0LjQsdC60Lgg0L/RgNC4IFNTQSIpDQpwcmludChwYXN0ZSgi0J7RiNC40LHQutCwINC/0YDQuCDQstGL0YfQuNGB0LvQtdC90LjQuCBDID0gMTogIiwgbXNlKGZfQywgciR0cmVuZCkgfD4gZm9ybWF0KHNjaWVudGlmaWMgPSBUUlVFLCBkaWdpdHMgPSAyKSAgKSkNCnByaW50KHBhc3RlKCLQntGI0LjQsdC60LAg0L/RgNC4INCy0YvRh9C40YHQu9C10L3QuNC4IGNvcyhwaS8xMik6ICIsIG1zZShmX2MsIHIkc2Vzb25hbCkgfD4gZm9ybWF0KHNjaWVudGlmaWMgPSBUUlVFLCBkaWdpdHMgPSAyKSkpDQoNCmxpbmVzKDE6biwgciR0cmVuZCkNCmxpbmVzKDE6biwgciRzZXNvbmFsKQ0KYGBgDQoNCiMjIyMg0J/RgNC+0LLQtdGA0LrQsCDRgNCw0LfQtNC10LvQuNC80L7RgdGC0Lgg0L3QtdC/0LXRgNC40L7QtNC40YfQtdGB0LrQuNGFINC60L7QvNC/0L7QvdC10L3RgiArINCw0LLRgtC+0LPRgNGD0L/Qv9C40YDQvtCy0LrQsCBTU0ENCg0KYGBge3J9DQpuIDwtIDk2KjItMQ0KTCA8LSA5Ng0KZXBzIDwtIDEvOTcNCg0KQyA8LSAxDQpvbWVnYV9jcyA8LSAxLzEyDQpvbWVnYV9zbiA8LSAxLzI0DQphIDwtIDEvMTAwDQpmX3N1bSA8LSBmdW5jdGlvbih4KXsNCiAgZl9jb25zdCh4LCBDID0gQykgKw0KICAgIGZfY29zKHgsIG9tZWdhID0gb21lZ2FfY3MpICsNCiAgICBmX2V4cCh4LCBhID0gYSkgKw0KICAgIGZfc2luKHgsIG9tZWdhID0gb21lZ2Ffc24pDQp9DQoNCg0KZl9DIDwtIGZfY29uc3QgfD4gZ2VuZXJhdGVfdHMobiwgQyA9IEMpDQpmX2MgPC0gZl9jb3MgfD4gZ2VuZXJhdGVfdHMobiwgb21lZ2EgPSBvbWVnYV9jcykNCmZfcyA8LSBmX3NpbiB8PiBnZW5lcmF0ZV90cyhuLCBvbWVnYSA9IG9tZWdhX3NuKQ0KZl9lIDwtIGZfZXhwIHw+IGdlbmVyYXRlX3RzKG4sIGEgPSBhKQ0KDQpmX24gPC0gZl9zdW0oMTpuKQ0KDQpsaWJyYXJ5KHh0YWJsZSkNCg0KIyDQqNCw0LMgMjog0KHQvtC30LTQsNC90LjQtSDQv9GA0LjQvNC10YDQsCDQtNCw0L3QvdGL0YUNCmRhdGEgPC0gZGF0YS5mcmFtZSgNCiAg0JzQtdGC0L7QtCA9IGMoIlNTQSIsICJDaVNTQSIpLA0KICBlX2VyciA9IGMoMjAsIDIwKSwNCiAgY19lcnIgPSBjKDIzLCAzNSksDQogIGVjX2VyciA9IGMoMjAsIDIwKSwNCiAgc2luX2VyciA9IGMgKDIwLCAyMCksDQogIGNvc19lcnIgPSBjKDEsIDEpDQopDQoNCg0KIyDQntGC0YDQuNGB0L7QstC60LAg0YDRj9C00LAgZl9uDQpwbG90KGZfbiwgdHlwZSA9ICJsIiwgbHdkID0gMywgY29sID0gJ3JlZCcsIHlsaW0gPSBjKC0yLCAxMCksDQogICAgIHhsYWIgPSAi0JLRgNC10LzRjyIsIHlsYWIgPSAi0JfQvdCw0YfQtdC90LjRjyDRgNGP0LTQsCIsIG1haW4gPSAi0KDQsNC30LvQvtC20LXQvdC40LUg0LLRgNC10LzQtdC90L3QvtCz0L4g0YDRj9C00LAiKQ0KDQojINCU0L7QsdCw0LLQu9C10L3QuNC1INC+0YLQtNC10LvRjNC90YvRhSDQutC+0LzQv9C+0L3QtdC90YLQvtCyIChmX0MsIGZfYywgZl9lKQ0KbGluZXMoZl9DLCBjb2wgPSAiYmx1ZSIpICAjINCa0L7QvNC/0L7QvdC10L3RgiBmX0MNCmxpbmVzKGZfYywgY29sID0gImJsdWUiKSAgIyDQmtC+0LzQv9C+0L3QtdC90YIgZl9jDQpsaW5lcyhmX2UsIGNvbCA9ICJibHVlIikgICMg0JrQvtC80L/QvtC90LXQvdGCIGZfZQ0KbGluZXMoZl9zLCBjb2wgPSAiYmx1ZSIpDQoNCiMg0JvQtdCz0LXQvdC00LANCmxlZ2VuZCgidG9wbGVmdCIsIGxlZ2VuZCA9IGMoItCS0LXRgdGMINGA0Y/QtCIsICLQmtC+0LzQv9C+0L3QtdC90YLRiyIpLCANCiAgICAgICBjb2wgPSBjKCJyZWQiLCAiYmx1ZSIpLCBsdHkgPSAxLCBsd2QgPSAzKQ0KDQoNCg0KDQoNCg0KDQoNCmMgPC0gY2lyY3VsYW50X1NTQShmX24sIEwgPSBMLCBleHRlbmRfZmxhZyA9IFRSVUUpDQojIHIgPC0gYyR0X3Nlcmllcw0KciA8LSBncm91cGluZ19jaXNzYShjLA0KICAgICAgICAgICAgICAgICAgICBncm91cHMgPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgICAgICMgdHJlbmQgPSBjKDAsIDEvMTAwKSwNCiAgICAgICAgICAgICAgICAgICAgICB0cmVuZCA9IGMoLTEsIDEvMjUpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzI0IC0gZXBzLCAxLzI0K2VwcykNCiAgICAgICAgICAgICAgICAgICAgKSkkdF9zZXJpZXMNCg0KZGF0YSRjb3NfZXJyWzJdIDwtIG1zZShmX3MsIHIkc2Vzb25hbF9zaW4pIHw+IGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzJdIDwtIG1zZShmX2MsIHIkc2Vzb25hbF9jb3MpIHw+IGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRlY19lcnJbMl0gPC0gbXNlKGZfQytmX2UsIHIkdHJlbmQpIHw+IGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCiMgcG5nKCJDOi9Vc2Vycy9uaWsxbS9EZXNrdG9wL9GD0L3QuNC6LzYg0YHQtdC8L9C60YPRgNGB0LDRhy/QotC10LrRgdGCINGA0LDQsdC+0YLRiy9pbWcvdHJlbmQgaW5zZXBhcmFiaWxpdHkvQ2lTU0EucG5nIikgICMg0YHQvtGF0YDQsNC90LXQvdC40LUg0LIg0YTQvtGA0LzQsNGC0LUgUE5HDQoNCnBsb3QoMTpuLCBmX24sIHR5cGUgPSAibCIsIGx3ZD0zLCB5bGltPSBjKC0yLCAxMCksIGNvbD0icmVkIiwNCiAgICAgeGxhYiA9ICLQktGA0LXQvNGPIiwgeWxhYiA9ICLQl9C90LDRh9C10L3QuNGPINGA0Y/QtNCwIiwgbWFpbiA9ICJDaVNTQSDRgNCw0LfQu9C+0LbQtdC90LjQtSDQstGA0LXQvNC10L3QvdC+0LPQviDRgNGP0LTQsCIpDQpsaW5lcygxOm4sIHIkdHJlbmQsIGNvbCA9ICJibHVlIikNCmxpbmVzKDE6biwgciRzZXNvbmFsX3NpbiwgY29sID0gImJsdWUiKQ0KbGluZXMoMTpuLCByJHNlc29uYWxfY29zLCBjb2wgPSAiYmx1ZSIpDQoNCiMg0JvQtdCz0LXQvdC00LANCmxlZ2VuZCgidG9wbGVmdCIsIGxlZ2VuZCA9IGMoItCS0LXRgdGMINGA0Y/QtCIsICLQmtC+0LzQv9C+0L3QtdC90YLRiyIpLCANCiAgICAgICBjb2wgPSBjKCJyZWQiLCAiYmx1ZSIpLCBsdHkgPSAxLCBsd2QgPSAzKQ0KDQojIGRldi5vZmYoKSAgIyDQt9Cw0LLQtdGA0YjQtdC90LjQtSDRgdC+0YXRgNCw0L3QtdC90LjRjw0KDQoNCg0KDQoNCg0KDQoNCg0KDQpzIDwtIHNzYShmX24sIEwpDQojZSA8LSBlb3NzYV9uZXcocywgbmVzdGVkLmdyb3VwcyA9IGxpc3QoMToxMCksIGNsdXN0X3R5cGUgPSAiZGlzdGFuY2UiLCBrPSA3KQ0KZSA8LSBlb3NzYShzLCAxOjEwLCBrID0gNykNCg0KZ19zZXNvbmFsIDwtIGdyb3VwaW5nLmF1dG8oZSwgYmFzZSA9ICJlaWdlbiIsDQogICAgICAgICAgICAgICAgICAgZnJlcS5iaW5zID0gbGlzdCh0cmVuZCA9IGMoMiplcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbDIgPSBjKDEvMjQtZXBzLCAxLzI0K2VwcyksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsMSA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSwNCiAgICAgICAgICAgICAgICAgICB0aHJlc2hvbGQgPSAwLjEpDQoNCg0KciA8LSBSc3NhOjpyZWNvbnN0cnVjdChlLCBncm91cHM9YyhsaXN0KGV4cCA9IDEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEMgPSAyDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdfc2Vzb25hbCkNCiAgICAgICAgICAgICAgICAgKQ0KDQpwbG90KHdjb3IoZSwgZ3JvdXBzID0gMToyNCksIHNjYWxlcyA9IGxpc3QoYXQgPSBjKDEwLCAyMCwgMzApKSkNCg0KZGF0YSRjX2VyclsxXSA8LSBtc2UoZl9DLCByJEMpIHw+IGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRlX2VyclsxXSA8LSBtc2UoZl9lLCByJGV4cCkgfD4gZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGNvc19lcnJbMV0gPC0gbXNlKGZfYywgciRzZXNvbmFsMSkgfD4gZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbMV0gPC0gbXNlKGZfcywgciRzZXNvbmFsMikgfD4gZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGVjX2VyclsxXSA8LSBtc2UoZl9DK2ZfZSwgciRDK3IkZXhwKSB8PiBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCg0KDQojIHBuZygiQzovVXNlcnMvbmlrMW0vRGVza3RvcC/Rg9C90LjQui82INGB0LXQvC/QutGD0YDRgdCw0Ycv0KLQtdC60YHRgiDRgNCw0LHQvtGC0YsvaW1nL3RyZW5kIGluc2VwYXJhYmlsaXR5L1NTQS5wbmciKSAgIyDRgdC+0YXRgNCw0L3QtdC90LjQtSDQsiDRhNC+0YDQvNCw0YLQtSBQTkcNCg0KcGxvdCgxOm4sIGZfbiwgdHlwZSA9ICJsIiwgbHdkPTMsIHlsaW09IGMoLTIsIDEwKSwgY29sPSJyZWQiLA0KICAgICB4bGFiID0gItCS0YDQtdC80Y8iLCB5bGFiID0gItCX0L3QsNGH0LXQvdC40Y8g0YDRj9C00LAiLCBtYWluID0gIlNTQSDRgNCw0LfQu9C+0LbQtdC90LjQtSDQstGA0LXQvNC10L3QvdC+0LPQviDRgNGP0LTQsCIpDQoNCmxpbmVzKDE6biwgciR0cmVuZCwgdHlwZSA9ICJsIiwgY29sPSJncmVlbiIpDQpsaW5lcygxOm4sIHIkZXhwLCB0eXBlID0gImwiLCB5bGltPSBjKC0yLCAxMCksIGNvbD0iYmx1ZSIpDQpsaW5lcygxOm4sIHIkQywgY29sID0gImJsdWUiKQ0KbGluZXMoMTpuLCByJHNlc29uYWwxLCBjb2wgPSAiYmx1ZSIpDQpsaW5lcygxOm4sIHIkc2Vzb25hbDIsIGNvbCA9ICJibHVlIikNCg0KIyDQm9C10LPQtdC90LTQsA0KbGVnZW5kKCJ0b3BsZWZ0IiwgbGVnZW5kID0gYygi0JLQtdGB0Ywg0YDRj9C0IiwgItCa0L7QvNC/0L7QvdC10L3RgtGLIiksIA0KICAgICAgIGNvbCA9IGMoInJlZCIsICJibHVlIiksIGx0eSA9IDEsIGx3ZCA9IDMpDQoNCg0KDQoNCg0KDQoNCiMg0KjQsNCzIDM6INCf0YDQtdC+0LHRgNCw0LfQvtCy0LDQvdC40LUg0LTQsNC90L3Ri9GFINCyINGE0L7RgNC80LDRgiBMYVRlWA0KdGFibGVfbGF0ZXggPC0geHRhYmxlKGRhdGEsIGNhcHRpb24gPSAiRXhhbXBsZSBUYWJsZSIpDQoNCiMg0KjQsNCzIDQ6INCS0YvQstC+0LQg0YLQsNCx0LvQuNGG0Ysg0LIgTGFUZVgg0YTQsNC50LsNCnByaW50KHRhYmxlX2xhdGV4LCBpbmNsdWRlLnJvd25hbWVzID0gRkFMU0UpDQoNCg0KDQoNCg0KYGBgDQoNCiMjIyMg0J/RgNC40LzQtdGAIGNvc1wqZXhwDQoNCmBgYHtyfQ0KbiA8LSA5NioyLTENCkwgPC0gOTYNCmVwcyA8LSAxLyhMKzEpDQoNCkMgPC0gMQ0Kb21lZ2FfY3MgPC0gMS8xMg0Kb21lZ2Ffc24gPC0gMS8yNA0KYSA8LSAxLzEwMA0Kb21lZ2FfZXhwIDwtIDEvNDgNCmZfc3VtIDwtIGZ1bmN0aW9uKHgpew0KICAgIGZfY29zKHgsIG9tZWdhID0gb21lZ2FfY3MpICsNCiAgICBmX2V4cF9tb2RfaGFybV9zZXJpZXMoeCwgYSA9IGEsIG9tZWdhID0gb21lZ2FfZXhwKSArDQogICAgZl9zaW4oeCwgb21lZ2EgPSBvbWVnYV9zbikgDQp9DQoNCg0KZl9jIDwtIGZfY29zIHw+IGdlbmVyYXRlX3RzKG4sIG9tZWdhID0gb21lZ2FfY3MpDQpmX3MgPC0gZl9zaW4gfD4gZ2VuZXJhdGVfdHMobiwgb21lZ2EgPSBvbWVnYV9zbikNCmZfZSA8LSBmX2V4cF9tb2RfaGFybV9zZXJpZXMgfD4gZ2VuZXJhdGVfdHMobiwgYSA9IGEsIG9tZWdhID0gb21lZ2FfZXhwKQ0KDQpmX24gPC0gZl9zdW0oMTpuKQ0KDQpsaWJyYXJ5KHh0YWJsZSkNCg0KIyDQqNCw0LMgMjog0KHQvtC30LTQsNC90LjQtSDQv9GA0LjQvNC10YDQsCDQtNCw0L3QvdGL0YUNCmRhdGEgPC0gZGF0YS5mcmFtZSgNCiAg0JzQtdGC0L7QtCA9IGMoIlNTQSIsICJDaVNTQSIpLA0KICBleHBfZXJyID0gYygyMCwgMjApLA0KICBzaW5fZXJyID0gYyAoMjAsIDIwKSwNCiAgY29zX2VyciA9IGMoMSwgMSkNCikNCg0KDQojINCe0YLRgNC40YHQvtCy0LrQsCDRgNGP0LTQsCBmX24NCnBsb3QoZl9uLCB0eXBlID0gImwiLCBsd2QgPSAzLCBjb2wgPSAncmVkJywgeWxpbSA9IGMoLTEwLCAxMCksDQogICAgIHhsYWIgPSAi0JLRgNC10LzRjyIsIHlsYWIgPSAi0JfQvdCw0YfQtdC90LjRjyDRgNGP0LTQsCIsIG1haW4gPSAi0KDQsNC30LvQvtC20LXQvdC40LUg0LLRgNC10LzQtdC90L3QvtCz0L4g0YDRj9C00LAiKQ0KDQojINCU0L7QsdCw0LLQu9C10L3QuNC1INC+0YLQtNC10LvRjNC90YvRhSDQutC+0LzQv9C+0L3QtdC90YLQvtCyIChmX0MsIGZfYywgZl9lKQ0KbGluZXMoZl9jLCBjb2wgPSAiYmx1ZSIpICAjINCa0L7QvNC/0L7QvdC10L3RgiBmX2MNCmxpbmVzKGZfZSwgY29sID0gImJsdWUiKSAgIyDQmtC+0LzQv9C+0L3QtdC90YIgZl9lDQpsaW5lcyhmX3MsIGNvbCA9ICJibHVlIikNCg0KIyDQm9C10LPQtdC90LTQsA0KbGVnZW5kKCJ0b3BsZWZ0IiwgbGVnZW5kID0gYygi0JLQtdGB0Ywg0YDRj9C0IiwgItCa0L7QvNC/0L7QvdC10L3RgtGLIiksIA0KICAgICAgIGNvbCA9IGMoInJlZCIsICJibHVlIiksIGx0eSA9IDEsIGx3ZCA9IDMpDQoNCg0KDQoNCg0KDQoNCg0KYyA8LSBjaXJjdWxhbnRfU1NBKGZfbiwgTCA9IEwsIGV4dGVuZF9mbGFnID0gVFJVRSkNCiMgciA8LSBjJHRfc2VyaWVzDQpyIDwtIGdyb3VwaW5nX2Npc3NhKGMsDQogICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgdHJlbmQgPSBjKDAsIDEvMjYtZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8yNC1lcHMsIDEvMjQrZXBzKQ0KICAgICAgICAgICAgICAgICAgICApKSR0X3Nlcmllcw0KDQpkYXRhJGNvc19lcnJbMl0gPC0gbXNlKGZfcywgciRzZXNvbmFsX3NpbikgfD4gZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbMl0gPC0gbXNlKGZfYywgciRzZXNvbmFsX2NvcykgfD4gZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGV4cF9lcnJbMl0gPC0gbXNlKGZfZSwgciR0cmVuZCkgfD4gZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCg0KIyBwbmcoIkM6L1VzZXJzL25pazFtL0Rlc2t0b3Av0YPQvdC40LovNiDRgdC10Lwv0LrRg9GA0YHQsNGHL9Ci0LXQutGB0YIg0YDQsNCx0L7RgtGLL2ltZy90cmVuZCBpbnNlcGFyYWJpbGl0eS9DaVNTQS5wbmciKSAgIyDRgdC+0YXRgNCw0L3QtdC90LjQtSDQsiDRhNC+0YDQvNCw0YLQtSBQTkcNCg0KcGxvdCgxOm4sIGZfbiwgdHlwZSA9ICJsIiwgbHdkPTMsIHlsaW09IGMoLTEwLCAxMCksIGNvbD0icmVkIiwNCiAgICAgeGxhYiA9ICLQktGA0LXQvNGPIiwgeWxhYiA9ICLQl9C90LDRh9C10L3QuNGPINGA0Y/QtNCwIiwgbWFpbiA9ICJDaVNTQSDRgNCw0LfQu9C+0LbQtdC90LjQtSDQstGA0LXQvNC10L3QvdC+0LPQviDRgNGP0LTQsCIpDQpsaW5lcygxOm4sIHIkdHJlbmQsIGNvbCA9ICJibHVlIikNCmxpbmVzKDE6biwgciRzZXNvbmFsX3NpbiwgY29sID0gImJsdWUiKQ0KbGluZXMoMTpuLCByJHNlc29uYWxfY29zLCBjb2wgPSAiYmx1ZSIpDQoNCiMg0JvQtdCz0LXQvdC00LANCmxlZ2VuZCgidG9wbGVmdCIsIGxlZ2VuZCA9IGMoItCS0LXRgdGMINGA0Y/QtCIsICLQmtC+0LzQv9C+0L3QtdC90YLRiyIpLCANCiAgICAgICBjb2wgPSBjKCJyZWQiLCAiYmx1ZSIpLCBsdHkgPSAxLCBsd2QgPSAzKQ0KDQojIGRldi5vZmYoKSAgIyDQt9Cw0LLQtdGA0YjQtdC90LjQtSDRgdC+0YXRgNCw0L3QtdC90LjRjw0KDQoNCg0KDQoNCg0KDQoNCg0KDQpzIDwtIHNzYShmX24sIEwpDQplIDwtIGVvc3NhX25ldyhzLCBuZXN0ZWQuZ3JvdXBzID0gbGlzdCgxOjMwKSwgY2x1c3RfdHlwZSA9ICJkaXN0YW5jZSIpDQoNCmdfc2Vzb25hbCA8LSBncm91cGluZy5hdXRvKGUsIGJhc2UgPSAiZWlnZW4iLA0KICAgICAgICAgICAgICAgICAgIGZyZXEuYmlucyA9IGxpc3QodHJlbmQgPSBjKDEvMjUtZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWwyID0gYygxLzI0LWVwcywgMS8yNCtlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbDEgPSBjKDEvMTItZXBzLCAxLzEyK2VwcykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksDQogICAgICAgICAgICAgICAgICAgdGhyZXNob2xkID0gMC4xKQ0KDQoNCnIgPC0gcmVjb25zdHJ1Y3QoZSwgZ3JvdXBzPSBnX3Nlc29uYWwpDQoNCnBsb3Qod2NvcihlLCBncm91cHMgPSAxOjI0KSwgc2NhbGVzID0gbGlzdChhdCA9IGMoMTAsIDIwLCAzMCkpKQ0KDQpkYXRhJGV4cF9lcnJbMV0gPC0gbXNlKGZfZSwgciR0cmVuZCkgIHw+IGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRjb3NfZXJyWzFdIDwtIG1zZShmX2MsIHIkc2Vzb25hbDEpIHw+IGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzFdIDwtIG1zZShmX3MsIHIkc2Vzb25hbDIpIHw+IGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCiMgcG5nKCJDOi9Vc2Vycy9uaWsxbS9EZXNrdG9wL9GD0L3QuNC6LzYg0YHQtdC8L9C60YPRgNGB0LDRhy/QotC10LrRgdGCINGA0LDQsdC+0YLRiy9pbWcvdHJlbmQgaW5zZXBhcmFiaWxpdHkvU1NBLnBuZyIpICAjINGB0L7RhdGA0LDQvdC10L3QuNC1INCyINGE0L7RgNC80LDRgtC1IFBORw0KDQpwbG90KDE6biwgZl9uLCB0eXBlID0gImwiLCBsd2Q9MywgeWxpbT0gYygtMTAsIDEwKSwgY29sPSJyZWQiLA0KICAgICB4bGFiID0gItCS0YDQtdC80Y8iLCB5bGFiID0gItCX0L3QsNGH0LXQvdC40Y8g0YDRj9C00LAiLCBtYWluID0gIlNTQSDRgNCw0LfQu9C+0LbQtdC90LjQtSDQstGA0LXQvNC10L3QvdC+0LPQviDRgNGP0LTQsCIpDQoNCmxpbmVzKDE6biwgciR0cmVuZCwgdHlwZSA9ICJsIiwgY29sPSJibHVlIikNCmxpbmVzKDE6biwgciRzZXNvbmFsMSwgY29sID0gImJsdWUiKQ0KbGluZXMoMTpuLCByJHNlc29uYWwyLCBjb2wgPSAiYmx1ZSIpDQoNCiMg0JvQtdCz0LXQvdC00LANCmxlZ2VuZCgidG9wbGVmdCIsIGxlZ2VuZCA9IGMoItCS0LXRgdGMINGA0Y/QtCIsICLQmtC+0LzQv9C+0L3QtdC90YLRiyIpLCANCiAgICAgICBjb2wgPSBjKCJyZWQiLCAiYmx1ZSIpLCBsdHkgPSAxLCBsd2QgPSAzKQ0KDQoNCg0KDQoNCg0KDQojINCo0LDQsyAzOiDQn9GA0LXQvtCx0YDQsNC30L7QstCw0L3QuNC1INC00LDQvdC90YvRhSDQsiDRhNC+0YDQvNCw0YIgTGFUZVgNCnRhYmxlX2xhdGV4IDwtIHh0YWJsZShkYXRhLCBjYXB0aW9uID0gIkV4YW1wbGUgVGFibGUiKQ0KDQojINCo0LDQsyA0OiDQktGL0LLQvtC0INGC0LDQsdC70LjRhtGLINCyIExhVGVYINGE0LDQudC7DQpwcmludCh0YWJsZV9sYXRleCwgaW5jbHVkZS5yb3duYW1lcyA9IEZBTFNFKQ0KDQoNCmBgYA0KDQojIyDQlNCw0L3QvdGL0LUgSVANCg0KYGBge3J9DQpsaWJyYXJ5KHJlYWR4bCkNCmRhdGEgPC0gcmVhZF9leGNlbCgiRGF0YS9JbnRlcm5hdGlvbmFsX0ZpbmFuY2lhbF9TdGF0aXN0aWNzXy54bHN4IikNCmRhdGEgfD4gaGVhZCgpDQpgYGANCg0K0J7RgtGA0LjRgdC+0LLQutCwINC00LDQvdC90YvRhSBJUA0KDQpgYGB7cn0NCmRhdGVzIDwtIHNlcShhcy5EYXRlKCIxOTcwLTAxLTAxIiksIGFzLkRhdGUoIjIwMTgtMS0zMCIpLCBieSA9ICJtb250aCIpDQpJUF92YWx1ZXMgPC0gZGF0YVsyLCAtYygxLCAyKV0gfD4gYXMuZG91YmxlKCkgDQpwbG90KGRhdGVzLCBJUF92YWx1ZXMsIHR5cGU9ImwiKQ0KYGBgDQoNCiMjIyMgQ2lzc2ENCg0K0J7RgtGA0LjRgdC+0LLQutCwINGC0YDQtdC90LTQvtCy0L7QuSDRgdC+0YHRgtCw0LLQu9GP0Y7RidC10Lkg0YfRkdGA0L3Ri9C8INGG0LLQtdGC0L7QvCwg0L7RgdC90L7QstC90L7QuSDQstGA0LXQvNC10L3QvdC+0Lkg0YDRj9C0IOKAlCDQutGA0LDRgdC90YvQvA0KDQpgYGB7cn0NCmRhdGFfc2xpY2UgPC0gMTo1MzcNCmRhdGVzX3NsaWNlIDwtIGRhdGVzW2RhdGFfc2xpY2VdDQpJUF92YWx1ZXNfc2xpY2UgPC0gSVBfdmFsdWVzW2RhdGFfc2xpY2VdDQplcHMgPC0gMS8xOTMNCg0KYyA8LSBjaXJjdWxhbnRfU1NBKElQX3ZhbHVlc19zbGljZSwgTCA9IDE5MiwgZXh0ZW5kX2ZsYWcgPSBUUlVFKQ0KciA8LSBjJHRfc2VyaWVzDQpyIDwtIGdyb3VwaW5nX2Npc3NhKGMsDQogICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgdHJlbmQgPSBjKDAsIDEvMTkyKSwNCiAgICAgICAgICAgICAgICAgICAgICBjeWNsZSA9IGMoMS85NywgNS85NSksDQogICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbCA9IGMoMS8xMywgMS8yKzAuMDAwMSkNCiAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICApJHRfc2VyaWVzDQpyX3Nlc29uYWwgPC0gIGdyb3VwaW5nX2Npc3NhKGMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzMSA9IGMoMTYvMTkyIC0gZXBzLCAxNi8xOTIgKyBlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgczIgPSBjKDMyLzE5MiAtIGVwcywgMzIvMTkyICsgZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMzID0gYyg0OC8xOTIgLSBlcHMsIDQ4LzE5MiArIGVwcyksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzNCA9IGMoNjQvMTkyIC0gZXBzLCA2NC8xOTIgKyBlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgczUgPSBjKDgwLzE5MiAtIGVwcywgODAvMTkyICsgZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHM2ID0gYyg5Ni8xOTIgLSBlcHMsIDk2LzE5MiArIGVwcykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICApJHRfc2VyaWVzDQojIGNpc3NhX3RyZW5kIDwtIHJbLDFdICsgclssMl0NCiMgY2lzc2FfY3ljbGUgPC0gclssIDM6MTFdIHw+IHJvd1N1bXMoKQ0KIyBjaXNzYV9zZXNvbmFsIDwtIHJbLCBjKDE3LCAzMywgNDksIDY1LCA4MSwgOTcpXSB8PiByb3dTdW1zKCkNCiMgY2lzc2FfcmVzaWR1YWxzIDwtIElQX3ZhbHVlc19zbGljZSAtIChjaXNzYV90cmVuZCArIGNpc3NhX2N5Y2xlICsgY2lzc2Ffc2Vzb25hbCkNCg0KY2lzc2FfdHJlbmQgPC0gciR0cmVuZA0KY2lzc2FfY3ljbGUgPC0gciRjeWNsZQ0KY2lzc2Ffc2Vzb25hbCA8LSBSZWR1Y2UoIisiLCByX3Nlc29uYWwgfD4gd2l0aGluKHJtKHJlc2lkdWFscykpKQ0KY2lzc2FfcmVzaWR1YWxzIDwtIElQX3ZhbHVlc19zbGljZSAtIChjaXNzYV90cmVuZCArIGNpc3NhX2N5Y2xlICsgY2lzc2Ffc2Vzb25hbCkNCg0KDQpwbG90KGRhdGVzX3NsaWNlLCBJUF92YWx1ZXNfc2xpY2UsDQogICAgIHR5cGU9ImwiLCBjb2wgPSAiYmxhY2siKQ0KbGluZXMoZGF0ZXNfc2xpY2UsIGNpc3NhX3RyZW5kLA0KICAgICAgdHlwZT0ibCIsIGNvbCA9ICJyZWQiKQ0KDQpwbG90KGRhdGVzX3NsaWNlLCBjaXNzYV9jeWNsZSwNCiAgICAgdHlwZT0ibCIsIGNvbCA9ICJyZWQiKQ0KDQpwbG90KGRhdGVzX3NsaWNlLCBjaXNzYV9zZXNvbmFsLA0KICAgICB0eXBlPSJsIiwgY29sID0gInJlZCIpDQoNCnBsb3QoZGF0ZXNfc2xpY2UsIGNpc3NhX3Jlc2lkdWFscywNCiAgICAgdHlwZT0ibCIsIGNvbCA9ICJyZWQiKQ0KDQpwbG90KGRhdGVzX3NsaWNlLCBJUF92YWx1ZXNfc2xpY2UsDQogICAgIHR5cGU9ImwiLCBjb2wgPSAiYmxhY2siKQ0KbGluZXMoZGF0ZXNfc2xpY2UsIGNpc3NhX3RyZW5kK2Npc3NhX2N5Y2xlK2Npc3NhX3Nlc29uYWwsDQogICAgICB0eXBlPSJsIiwgY29sID0gInJlZCIpDQpgYGANCg0KIyMjIyBTU0EgZm9zc2ENCg0KYGBge3J9DQpzIDwtIHNzYShJUF92YWx1ZXNfc2xpY2UsIEwgPSAxOTIpDQplIDwtIGZvc3NhKHMsIDE6KDExKSkNCiMgZSA8LSBlb3NzYV9uZXcocywgbmVzdGVkLmdyb3VwcyA9IGxpc3QoMTozMCksIGNsdXN0X3R5cGUgPSAiZGlzdGFuY2UiKQ0KZXBzIDwtIDEvMTkzDQoNCmdyb3VwcyA8LSBncm91cGluZy5hdXRvKGUsDQogICAgICAgICAgICAgICAgICAgZnJlcS5iaW5zID0gbGlzdCh0cmVuZCA9IGMoMS8xOTIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3ljbGUgPSBjKDEvOTcsIDUvOTUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgczEgPSBjKDE2LzE5MiAtIGVwcywgMTYvMTkyICsgZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMyID0gYygzMi8xOTIgLSBlcHMsIDMyLzE5MiArIGVwcyksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzMyA9IGMoNDgvMTkyIC0gZXBzLCA0OC8xOTIgKyBlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgczQgPSBjKDY0LzE5MiAtIGVwcywgNjQvMTkyICsgZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHM1ID0gYyg4MC8xOTIgLSBlcHMsIDgwLzE5MiArIGVwcyksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzNiA9IGMoOTYvMTkyIC0gZXBzLCA5Ni8xOTIgKyBlcHMpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLA0KICAgICAgICAgICAgICAgICAgIHRocmVzaG9sZCA9IDApDQoNCg0KcGxvdCh3Y29yKGUsIGdyb3VwcyA9IDE6MzApLCBzY2FsZXMgPSBsaXN0KGF0ID0gYygxMCwgMjAsIDMwKSksDQogICAgIG1haW4gPSAiVy1jb3JyZWxhdGlvbiBtYXRyaXggU1NBIChmb3NzYSkiKQ0KDQpyIDwtIHJlY29uc3RydWN0KGUsIGdyb3Vwcz1ncm91cHMpDQoNCnNzYV90cmVuZF9mIDwtIHIkdHJlbmQNCnNzYV9jeWNsZV9mIDwtIHIkY3ljbGUNCnNzYV9zZXNvbmFsX2YgPC0gciRzMSArIHIkczIgKyByJHMzICsgciRzNCArIHIkczUgKyByJHM2DQpzc2FfcmVzaWR1YWxzX2YgPC0gSVBfdmFsdWVzX3NsaWNlIC0gKHNzYV90cmVuZF9mICsgc3NhX2N5Y2xlX2YgKyBzc2Ffc2Vzb25hbF9mKQ0KDQpwbG90KGRhdGVzX3NsaWNlLCBJUF92YWx1ZXNfc2xpY2UsDQogICAgIHR5cGU9ImwiLCBjb2wgPSAiYmxhY2siKQ0KbGluZXMoZGF0ZXNfc2xpY2UsIHNzYV90cmVuZF9mLA0KICAgICAgdHlwZT0ibCIsIGNvbCA9ICJtYWdlbnRhIikNCg0KcGxvdChkYXRlc19zbGljZSwgc3NhX2N5Y2xlX2YsIA0KICAgICB0eXBlPSJsIiwgY29sID0gIm1hZ2VudGEiKQ0KDQpwbG90KGRhdGVzX3NsaWNlLCBzc2Ffc2Vzb25hbF9mLCANCiAgICAgdHlwZT0ibCIsIGNvbCA9ICJtYWdlbnRhIikNCg0KcGxvdChkYXRlc19zbGljZSwgc3NhX3Jlc2lkdWFsc19mLA0KICAgICB0eXBlPSJsIiwgY29sID0gIm1hZ2VudGEiKQ0KDQpgYGANCg0KIyMjIyBTU0EgZW9zc2ENCg0KYGBge3J9DQpsaWJyYXJ5KFJzc2EpDQpzb3VyY2UoImVvc3NhX25ldy5yIikNCnMgPC0gc3NhKElQX3ZhbHVlc19zbGljZSwgTCA9IDE5MikNCmUgPC0gZW9zc2FfbmV3KHMsIG5lc3RlZC5ncm91cHMgPSBsaXN0KDE6MjApLCBjbHVzdF90eXBlID0gImRpc3RhbmNlIikNCg0KDQoNCg0KZ3JvdXBzIDwtIGdyb3VwaW5nLmF1dG8oZSwNCiAgICAgICAgICAgICAgICAgICBmcmVxLmJpbnMgPSBsaXN0KHRyZW5kID0gYygxLzE5MiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjeWNsZSA9IGMoMS85NywgNS85NSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzMSA9IGMoMTYvMTkyIC0gZXBzLCAxNi8xOTIgKyBlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgczIgPSBjKDMyLzE5MiAtIGVwcywgMzIvMTkyICsgZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMzID0gYyg0OC8xOTIgLSBlcHMsIDQ4LzE5MiArIGVwcyksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzNCA9IGMoNjQvMTkyIC0gZXBzLCA2NC8xOTIgKyBlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgczUgPSBjKDgwLzE5MiAtIGVwcywgODAvMTkyICsgZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHM2ID0gYyg5Ni8xOTIgLSBlcHMsIDk2LzE5MiArIGVwcykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksDQogICAgICAgICAgICAgICAgICAgdGhyZXNob2xkID0gMCkNCnBsb3Qod2NvcihlLCBncm91cHMgPSAxOjMwKSwgc2NhbGVzID0gbGlzdChhdCA9IGMoMTAsIDIwLCAzMCkpLA0KICAgICBtYWluID0gIlctY29ycmVsYXRpb24gbWF0cml4IFNTQSAoZW9zc2EpIikNCg0KciA8LSByZWNvbnN0cnVjdChlLCBncm91cHM9Z3JvdXBzKQ0KDQpzc2FfdHJlbmQgPC0gciR0cmVuZA0Kc3NhX2N5Y2xlIDwtIHIkY3ljbGUNCnNzYV9zZXNvbmFsIDwtIHIkczEgKyByJHMyICsgciRzMyArIHIkczQgKyByJHM1ICsgciRzNg0Kc3NhX3Jlc2lkdWFscyA8LSBJUF92YWx1ZXNfc2xpY2UgLSAoc3NhX3RyZW5kICsgc3NhX2N5Y2xlICsgc3NhX3Nlc29uYWwpDQoNCnBsb3QoZGF0ZXNfc2xpY2UsIElQX3ZhbHVlc19zbGljZSwNCiAgICAgdHlwZT0ibCIsIGNvbCA9ICJibGFjayIpDQpsaW5lcyhkYXRlc19zbGljZSwgc3NhX3RyZW5kLA0KICAgICAgdHlwZT0ibCIsIGNvbCA9ICJibHVlIikNCg0KcGxvdChkYXRlc19zbGljZSwgc3NhX2N5Y2xlLCANCiAgICAgdHlwZT0ibCIsIGNvbCA9ICJibHVlIikNCg0KcGxvdChkYXRlc19zbGljZSwgc3NhX3Nlc29uYWwsIA0KICAgICB0eXBlPSJsIiwgY29sID0gImJsdWUiKQ0KDQpwbG90KGRhdGVzX3NsaWNlLCBzc2FfcmVzaWR1YWxzLA0KICAgICB0eXBlPSJsIiwgY29sID0gImJsdWUiKQ0KYGBgDQoNCmBgYHtyfQ0KcGxvdChkYXRlc19zbGljZSwgSVBfdmFsdWVzX3NsaWNlLA0KICAgICBtYWluID0gIklQIFVTQSDRgtGA0LXQvdC0Iix4bGFiID0gItCS0YDQtdC80Y8iLCB5bGFiID0gItCX0L3QsNGH0LXQvdC40LUiLA0KICAgICB0eXBlPSJsIiwgY29sID0gImJsYWNrIikNCmxpbmVzKGRhdGVzX3NsaWNlLCBzc2FfdHJlbmQsDQogICAgICB0eXBlPSJsIiwgY29sID0gImJsdWUiLCBsd2Q9MikNCmxpbmVzKGRhdGVzX3NsaWNlLCBzc2FfdHJlbmRfZiwNCiAgICAgIHR5cGU9ImwiLCBjb2wgPSAibWFnZW50YSIsIGx3ZD0yKQ0KbGluZXMoZGF0ZXNfc2xpY2UsIGNpc3NhX3RyZW5kLA0KICAgICAgdHlwZT0ibCIsIGNvbCA9ICJyZWQiLCBsd2Q9MikNCiMg0JvQtdCz0LXQvdC00LANCmxlZ2VuZCgidG9wbGVmdCIsIGxlZ2VuZCA9IGMoItCS0LXRgdGMINGA0Y/QtCIsICJDaVNTQSDRgtGA0LXQvdC0IiwgIlNTQSDRgtGA0LXQvdC0IChlb3NzYSkiLCAiU1NBINGC0YDQtdC90LQgKGZvc3NhKSIpLCANCiAgICAgICBjb2wgPSBjKCJibGFjayIsICJyZWQiLCAiYmx1ZSIsICJtYWdlbnRhIiksIGx0eSA9IDEsIGx3ZCA9IDMpDQoNCg0KcGxvdChkYXRlc19zbGljZSwgc3NhX2N5Y2xlLA0KICAgICBtYWluID0gIklQIFVTQSDRhtC40LrQu9C40YfQvdC+0YHRgtGMIiwgeGxhYiA9ICLQktGA0LXQvNGPIiwgeWxhYiA9ICLQl9C90LDRh9C10L3QuNC1IiwNCiAgICAgdHlwZT0ibCIsIGNvbCA9ICJibHVlIiwgeWxpbT1jKC0xMCwgMTApLCBsd2Q9MikNCmxpbmVzKGRhdGVzX3NsaWNlLCBjaXNzYV9jeWNsZSwNCiAgICAgIHR5cGU9ImwiLCBjb2wgPSAicmVkIiwgbHdkPTIpDQpsaW5lcyhkYXRlc19zbGljZSwgc3NhX2N5Y2xlX2YsDQogICAgICB0eXBlPSJsIiwgY29sID0gIm1hZ2VudGEiLCBsd2Q9MikNCiMg0JvQtdCz0LXQvdC00LANCmxlZ2VuZCgidG9wbGVmdCIsIGxlZ2VuZCA9IGMoIkNpU1NBIiwgIlNTQSAoZW9zc2EpIiwgIlNTQSAoZm9zc2EpIiksIA0KICAgICAgIGNvbCA9IGMoInJlZCIsICJibHVlIiwgIm1hZ2VudGEiKSwgbHR5ID0gMSwgbHdkID0gMykNCg0KDQpwbG90KGRhdGVzX3NsaWNlLCBJUF92YWx1ZXNfc2xpY2UsDQogICAgIG1haW4gPSAiSVAgVVNBINGC0YDQtdC90LQgKyDRhtC40LrQu9C40YfQvdC+0YHRgtGMIix4bGFiID0gItCS0YDQtdC80Y8iLCB5bGFiID0gItCX0L3QsNGH0LXQvdC40LUiLA0KICAgICB0eXBlPSJsIiwgY29sID0gImJsYWNrIikNCmxpbmVzKGRhdGVzX3NsaWNlLCBzc2FfdHJlbmQgKyBzc2FfY3ljbGUsDQogICAgICB0eXBlPSJsIiwgY29sID0gImJsdWUiLCBsd2Q9MikNCmxpbmVzKGRhdGVzX3NsaWNlLCBzc2FfdHJlbmRfZiArIHNzYV9jeWNsZV9mLA0KICAgICAgdHlwZT0ibCIsIGNvbCA9ICJtYWdlbnRhIiwgbHdkPTIpDQpsaW5lcyhkYXRlc19zbGljZSwgY2lzc2FfdHJlbmQgKyBjaXNzYV9jeWNsZSwNCiAgICAgIHR5cGU9ImwiLCBjb2wgPSAicmVkIiwgbHdkPTIpDQojINCb0LXQs9C10L3QtNCwDQpsZWdlbmQoInRvcGxlZnQiLCBsZWdlbmQgPSBjKCLQktC10YHRjCDRgNGP0LQiLCAiQ2lTU0EiLCAiU1NBIChlb3NzYSkiLCAiU1NBIChmb3NzYSkiKSwgDQogICAgICAgY29sID0gYygiYmxhY2siLCAicmVkIiwgImJsdWUiLCAibWFnZW50YSIpLCBsdHkgPSAxLCBsd2QgPSAzKQ0KDQoNCmBgYA0KDQpgYGB7cn0NCiMg0J3QsNGB0YLRgNC+0LnQutCwINCz0YDQsNGE0LjQutC+0LIg0LTQu9GPINC+0YLQvtCx0YDQsNC20LXQvdC40Y8g0LTQstGD0YUg0LPRgNCw0YTQuNC60L7QsiDQvtC00LjQvSDQv9C+0LQg0LTRgNGD0LPQuNC8INGBINC+0LHRidC10Lkg0L7RgdGM0Y4gWA0KbGF5b3V0KG1hdHJpeChjKDEsIDIpLCBucm93ID0gMiwgYnlyb3cgPSBUUlVFKSwgaGVpZ2h0cyA9IGMoMSwgMS4yKSkNCg0KIyDQn9C+0YHRgtGA0L7QtdC90LjQtSDQv9C10YDQstC+0LPQviDQs9GA0LDRhNC40LrQsA0KcGFyKG1hciA9IGMoMiwgNCwgMiwgMikpICMg0KPQvNC10L3RjNGI0LXQvdC40LUg0L3QuNC20L3QtdCz0L4g0L7RgtGB0YLRg9C/0LANCnBsb3QoZGF0ZXNfc2xpY2UsIHNzYV9zZXNvbmFsLCB0eXBlID0gImwiLCBjb2wgPSAiYmx1ZSIsIGx3ZCA9IDEsDQogICAgIG1haW4gPSAiU1NBIChlb3NzYSkg0YHQtdC30L7QvdC90L7RgdGC0YwiLCB4bGFiID0gIiIsIHlsYWIgPSAi0JfQvdCw0YfQtdC90LjQtSIpDQojINCU0L7QsdCw0LLQu9C10L3QuNC1INC+0YHQuCBYINCy0L3QuNC30YMg0L/QtdGA0LLQvtCz0L4g0LPRgNCw0YTQuNC60LAsINC90L4g0YEg0L/Rg9GB0YLRi9C80Lgg0LzQtdGC0LrQsNC80LgNCmF4aXMoMSwgbGFiZWxzID0gRkFMU0UpDQoNCiMg0J/QvtGB0YLRgNC+0LXQvdC40LUg0LLRgtC+0YDQvtCz0L4g0LPRgNCw0YTQuNC60LANCnBhcihtYXIgPSBjKDUsIDQsIDIsIDIpKSAjINCj0LLQtdC70LjRh9C10L3QuNC1INC90LjQttC90LXQs9C+INC+0YLRgdGC0YPQv9CwDQpwbG90KGRhdGVzX3NsaWNlLCBzc2Ffc2Vzb25hbF9mLCB0eXBlID0gImwiLCBjb2wgPSAibWFnZW50YSIsIGx3ZCA9IDEsDQogICAgIG1haW4gPSAiU1NBIChmb3NzYSkg0YHQtdC30L7QvdC90L7RgdGC0YwiLCB4bGFiID0gItCS0YDQtdC80Y8iLCB5bGFiID0gItCX0L3QsNGH0LXQvdC40LUiKQ0KDQpwYXIobWFyID0gYygzLCA0LCAyLCAyKSkgIyDQo9Cy0LXQu9C40YfQtdC90LjQtSDQvdC40LbQvdC10LPQviDQvtGC0YHRgtGD0L/QsA0KcGxvdChkYXRlc19zbGljZSwgY2lzc2Ffc2Vzb25hbCwgdHlwZSA9ICJsIiwgY29sID0gInJlZCIsIGx3ZCA9IDEsDQogICAgIG1haW4gPSAiQ2lTU0Eg0YHQtdC30L7QvdC90L7RgdGC0YwiLCB4bGFiID0gItCS0YDQtdC80Y8iLCB5bGFiID0gItCX0L3QsNGH0LXQvdC40LUiKQ0KDQojINCS0L7RgdGB0YLQsNC90L7QstC70LXQvdC40LUg0LzQsNC60LXRgtCwINC/0L4g0YPQvNC+0LvRh9Cw0L3QuNGODQpsYXlvdXQoMSkNCg0KDQpgYGANCg0KYGBge3J9DQpwbG90KGRhdGVzX3NsaWNlLCBzc2FfcmVzaWR1YWxzLCANCiAgICAgbWFpbiA9ICJJUCBVU0Eg0L7RgdGC0LDRgtC+0LoiLCB4bGFiID0gItCS0YDQtdC80Y8iLCB5bGFiID0gItCX0L3QsNGH0LXQvdC40LUiLA0KICAgICB0eXBlPSJsIiwgY29sID0gImJsdWUiLCB5bGltPWMoLTIsIDIpKQ0KbGluZXMoZGF0ZXNfc2xpY2UsIGNpc3NhX3Jlc2lkdWFscywNCiAgICAgIHR5cGU9ImwiLCBjb2wgPSAicmVkIikNCmxpbmVzKGRhdGVzX3NsaWNlLCBzc2FfcmVzaWR1YWxzX2YsDQogICAgICB0eXBlPSJsIiwgY29sID0gIm1hZ2VudGEiKQ0KbGVnZW5kKCJ0b3BsZWZ0IiwgbGVnZW5kID0gYygiQ2lTU0EiLCAiU1NBIChlb3NzYSkiLCAiU1NBIChmb3NzYSkiKSwgDQogICAgICAgY29sID0gYygicmVkIiwgImJsdWUiLCAibWFnZW50YSIpLCBsdHkgPSAxLCBsd2QgPSAzKQ0KYGBgDQoNCmBgYHtyfQ0Kc3NhX3Jlc2lkdWFscyB8PiBkZW5zaXR5KCkgfD4gcGxvdCgpDQpjaXNzYV9yZXNpZHVhbHMgfD4gZGVuc2l0eSgpIHw+IHBsb3QoKQ0KYGBgDQoNCiMjINCe0YLQtNC10LvQtdC90LjQtSDRgdC40LPQvdCw0LvQsCDQvtGCINGI0YPQvNCwDQoNCmBgYHtyfQ0Kc2V0LnNlZWQoMTAwKQ0KDQpuX21zZV90ZXN0cyA8LSBmdW5jdGlvbihuKXsNCiAgbiA8LSA5NioyLTENCiAgTCA8LSA5Ng0KICBzaWdtYSA8LSAwLjENCiAgDQogIA0KICBDIDwtIDENCiAgb21lZ2FfY3MgPC0gMS8xMg0KICBvbWVnYV9zbiA8LSAxLzI0DQogIGEgPC0gMS8xMDANCiAgZl9zdW0gPC0gZnVuY3Rpb24oeCl7DQogICAgZl9jb25zdCh4LCBDID0gQykgKw0KICAgICAgZl9jb3MoeCwgb21lZ2EgPSBvbWVnYV9jcykgKw0KICAgICAgZl9leHAoeCwgYSA9IGEpICsNCiAgICAgIGZfc2luKHgsIG9tZWdhID0gb21lZ2Ffc24pDQogIH0NCiAgDQogIA0KICBmX0MgPC0gZl9jb25zdCB8PiBnZW5lcmF0ZV90cyhuLCBDID0gQykNCiAgZl9jIDwtIGZfY29zIHw+IGdlbmVyYXRlX3RzKG4sIG9tZWdhID0gb21lZ2FfY3MpDQogIGZfcyA8LSBmX3NpbiB8PiBnZW5lcmF0ZV90cyhuLCBvbWVnYSA9IG9tZWdhX3NuKQ0KICBmX2UgPC0gZl9leHAgfD4gZ2VuZXJhdGVfdHMobiwgYSA9IGEpDQogIA0KICBtc2VfbHN0IDwtIGxpc3QoKQ0KICBmb3IgKGkgaW4gMTpuKSB7DQogICAgZl9ub2lzZSA8LSBybm9ybShuLCBzZCA9IHNpZ21hKQ0KICAgIA0KICAgIGZfbiA8LSBmX3N1bSgxOm4pICsgZl9ub2lzZQ0KICAgIA0KICAgIA0KICAgIA0KICAgIGMgPC0gY2lyY3VsYW50X1NTQShmX24sIEwgPSBMLCBleHRlbmRfZmxhZyA9IFRSVUUpDQogICAgIyByIDwtIGMkdF9zZXJpZXMNCiAgICByIDwtIGdyb3VwaW5nX2Npc3NhKGMsIGdyb3Vwcz0gbGlzdCh0cmVuZCA9IGMoMCwgMS8xMDAwKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbDIgPSBjKDEvMjUsIDEvMjMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWwxID0gYygxLzEzLCAxLzEwKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkpJHRfc2VyaWVzDQogICAgDQogICAgIyBtc2VfbHN0JGNpc3NhIDwtIGMobXNlX2xzdCRjaXNzYSwgbXNlKGZfc3VtKDE6biksIHJbLCA5XSArIHJbLCA1XSArIHJbLCAxXSkpIA0KICAgIG1zZV9sc3QkY2lzc2EgPC0gYyhtc2VfbHN0JGNpc3NhLA0KICAgICAgICAgICAgICAgICAgICAgICBtc2UoZl9zdW0oMTpuKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHIkdHJlbmQgKyByJHNlc29uYWwxICsgciRzZXNvbmFsMikpIA0KICAgIA0KICAgIA0KICAgIA0KICAgIA0KICAgIHMgPC0gc3NhKGZfbiwgTCkNCiAgICAjIGUgPC0gZW9zc2EocywgMToxMCwgayA9IDYpDQogICAgZSA8LSBmb3NzYShzKQ0KICAgIA0KICAgIGdfc2Vzb25hbCA8LSBncm91cGluZy5hdXRvKGUsIGJhc2UgPSAiZWlnZW4iLA0KICAgICAgICAgICAgICAgICAgICAgICBmcmVxLmJpbnMgPSBsaXN0KHRyZW5kID0gMS8xMDAwLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsMiA9IGMoMS8yNSwgMS8yMyksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbDEgPSBjKDEvMTMsIDEvMTApDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSwNCiAgICAgICAgICAgICAgICAgICAgICAgdGhyZXNob2xkID0gMC41KQ0KICAgIA0KICAgIHIgPC0gcmVjb25zdHJ1Y3QoZSwgZ3JvdXBzPWMobGlzdChleHAgPSAxLCBDID0gMiksIGdfc2Vzb25hbCkpDQogICAgDQogICAgbXNlX2xzdCRzc2EgPC0gDQogICAgICBjKG1zZV9sc3Qkc3NhLCBtc2UoZl9zdW0oMTpuKSwgciR0cmVuZCArIHIkc2Vzb25hbDIgKyByJHNlc29uYWwxKSkNCiANCiAgfQ0KICByZXR1cm4obXNlX2xzdCkNCn0NCg0KcmVzX21zZV90ZXN0IDwtIG5fbXNlX3Rlc3RzKDEwMCkNCg0KYGBgDQoNCmBgYHtyfQ0KIyDQntGG0LXQvdC60LAg0L/Qu9C+0YLQvdC+0YHRgtC4DQpkZW5zaXR5X2VzdGltYXRlX2Npc3NhIDwtIGRlbnNpdHkocmVzX21zZV90ZXN0JGNpc3NhKQ0KDQojINCf0L7RgdGC0YDQvtC10L3QuNC1INCz0YDQsNGE0LjQutCwINC/0LvQvtGC0L3QvtGB0YLQuA0KcGxvdChkZW5zaXR5X2VzdGltYXRlX2Npc3NhLCBtYWluID0gItCe0YbQtdC90LrQsCDQv9C70L7RgtC90L7RgdGC0LgiLCANCiAgICAgeGxhYiA9ICLQl9C90LDRh9C10L3QuNC1IiwgeWxhYiA9ICLQn9C70L7RgtC90L7RgdGC0YwiLCANCiAgICAgY29sID0gImJsdWUiLCBsd2QgPSAyKQ0KDQpkZW5zaXR5X2VzdGltYXRlX3NzYSA8LSBkZW5zaXR5KHJlc19tc2VfdGVzdCRzc2EpDQoNCiMg0J/QvtGB0YLRgNC+0LXQvdC40LUg0LPRgNCw0YTQuNC60LAg0L/Qu9C+0YLQvdC+0YHRgtC4DQpwbG90KGRlbnNpdHlfZXN0aW1hdGVfc3NhLCBtYWluID0gItCe0YbQtdC90LrQsCDQv9C70L7RgtC90L7RgdGC0LgiLCANCiAgICAgeGxhYiA9ICLQl9C90LDRh9C10L3QuNC1IiwgeWxhYiA9ICLQn9C70L7RgtC90L7RgdGC0YwiLCANCiAgICAgY29sID0gImJsdWUiLCBsd2QgPSAyKQ0KDQpyZXNfbXNlX3Rlc3QkY2lzc2EgfD4gc3VtbWFyeSgpDQpyZXNfbXNlX3Rlc3QkY2lzc2EgfD4gc2QoKQ0KcmVzX21zZV90ZXN0JHNzYSB8PiBzdW1tYXJ5KCkNCnJlc19tc2VfdGVzdCRzc2EgfD4gc2QoKQ0KYGBgDQoNCiMjINCa0LDQuiDQstGL0L/QvtC70L3Rj9C10YLRgdGPINGA0LDRgdGI0LjRgNC10L3QuNC1INGA0Y/QtNCwDQoNCmBgYHtyfQ0KSVBfdmFsdWVzX3NsaWNlIHw+IGV4dGVuZCgxOTIpIHw+DQogIHBsb3QodHlwZT0ibCIsIGx3ZCA9IDMsIHlsYWI9ItCX0L3QsNGH0LXQvdC40Y8iLCB4bGFiID0gItCY0L3QtNC10LrRgdGLIiwgbWFpbj0i0KDQsNGB0YjQuNGA0LXQvdC40LUg0LLRgNC10LzQtdC90L3QvtCz0L4g0YDRj9C00LAgSVAgdmFsdWVzIikNCmxpbmVzKCgxOTI6KGxlbmd0aChJUF92YWx1ZXNfc2xpY2UpICsgMTkyIC0xKSkgKyAxLCBJUF92YWx1ZXNfc2xpY2UsIHR5cGU9ImwiLCBjb2w9InJlZCIpDQoNCmBgYA0KDQpgYGB7cn0NCm4gPC0gOTYqMiArIDYNCnggPC0gMDoobi0xKQ0KeSA8LSBzaW4oMipwaS8xMiAqIHgpDQpMIDwtIDk2KzYNCnBsb3QoeSB8PiBleHRlbmQoTCksIHR5cGU9ImwiLCBsd2QgPSA0LCB5bGFiPSLQl9C90LDRh9C10L3QuNGPIiwgeGxhYiA9ICLQmNC90LTQtdC60YHRiyIsIG1haW49ItCg0LDRgdGI0LjRgNC10L3QuNC1INCy0YDQtdC80LXQvdC90L7Qs9C+INGA0Y/QtNCwIHNpbiIpDQpsaW5lcygoeCtMKzEpLCB5LCB0eXBlPSJsIiwgY29sPSJyZWQiLCBsd2QgPSAyKQ0KYGBgDQoNCiMjIENpU1NBINGH0LXRgNC10Lcg0KTRg9GA0YzQtQ0KDQojIyMgSVBfdmFsdWVzDQoNCmBgYHtyfQ0KY2lzc2FfbGlrZV9mb3VyaWVyX3RyYW5zZm9ybSA8LSBmdW5jdGlvbih0cywgTCl7DQogIHJlY29uc3RydWN0X2ZmdCA8LSBmdW5jdGlvbih4LCB5LCBmcmVxdWVuY2llcykgew0KICAgIGZmdF95IDwtIGZmdCh5KQ0KICANCiAgICBhbXBsaXR1ZGVzIDwtIE1vZChmZnRfeSkNCiAgICBwaGFzZXMgPC0gQXJnKGZmdF95KQ0KICAgIA0KICAgIHJlY29uc3RydWN0ZWQgPC0gbWF0cml4KDAsIGxlbmd0aChhbXBsaXR1ZGVzKSwgbGVuZ3RoKHgpKQ0KICAgIG4gPC0gbGVuZ3RoKGFtcGxpdHVkZXMpDQogICAgZm9yIChpIGluIDE6KGxlbmd0aChhbXBsaXR1ZGVzKSkpIHsNCiAgICAgIHJlY29uc3RydWN0ZWRbaSwgXSA8LQ0KICAgICAgICBhbXBsaXR1ZGVzW2ldICogDQogICAgICAgIGNvcygyICogcGkgKiBmcmVxdWVuY2llc1tpXSAqICh4KSArIHBoYXNlc1tpXSkgLw0KICAgICAgICBuDQogICAgfQ0KICAgIHJldHVybihsaXN0KA0KICAgICAgdHMgPSByZWNvbnN0cnVjdGVkLA0KICAgICAgZnJlcXVlbmNpZXMgPSBmcmVxdWVuY2llcw0KICAgICAgKSkNCiAgfQ0KICANCiAgbiA8LSBsZW5ndGgodHMpDQogIHggPC0gMDoobi0xKQ0KICBMIDwtIEwNCiAgZnJlcXVlbmNpZXMgPC0gKDA6KEwtMSkpIC8gTA0KICB5IDwtIHRzDQogIHlfbWFpbiA8LSB5DQogIHhfbWFpbiA8LSB4DQogIA0KICBYIDwtIGhhbmtlbCh5LCBMKQ0KICBLIDwtIGRpbShYKVsyXQ0KICByZXMgPC0gbGlzdCgpDQogIGZvciAoaSBpbiAxOkspew0KICAgIHkgPC0gWFssIGldDQogICAgeCA8LSB4X21haW5bMTooMSArIEwgLSAxKV0NCiAgICByZXNbW2ldXSA8LSByZWNvbnN0cnVjdF9mZnQoeCwgeSwgZnJlcXVlbmNpZXMpJHRzDQogIH0NCiAgDQogICMgZm9yIChpIGluIDE6TCl7DQogICMgICBwbG90KHgsIHJlc1tbaV1dWzksIF0pDQogICMgfQ0KICANCiAgcmVzX211bHQgPC0gcmVzDQogICMgcmVzDQogIA0KICBhdmVyYWdpbmcgPC0gZnVuY3Rpb24ocmVzX2NvbXBfd2lzZV9tdWx0KXsNCiAgICBLIDwtIGRpbShYKVsyXQ0KICAgIGNvdW50ZXJzIDwtIHJlcCgwLCBuKQ0KICAgIHJlcyA8LSBtYXRyaXgoMCwgbmNvbCA9IG4sIG5yb3cgPSBMKQ0KICAgIGZvciAoaSBpbiAxOmxlbmd0aChyZXNfY29tcF93aXNlX211bHQpKXsNCiAgICAgIHJlc1ssIGk6KGkrTC0xKV0gPC0gcmVzWywgaTooaStMLTEpXSArIHJlc19jb21wX3dpc2VfbXVsdFtbaV1dDQogICAgICBjb3VudGVyc1tpOihpK0wtMSldIDwtIGNvdW50ZXJzW2k6KGkrTC0xKV0gKyAxDQogICAgfQ0KICAgIGZvciAoaSBpbiAxOm4pew0KICAgICAgcmVzWywgaV0gPC0gcmVzWywgaV0gLyBjb3VudGVyc1tpXQ0KICAgIH0NCiAgICByZXMNCiAgfQ0KICANCiAgYXZyIDwtIGF2ZXJhZ2luZyhyZXNfbXVsdCkNCiAgDQogIGdyb3VwX2J5X2VsZW1lbnRhcnlfZnJlcV9mb3VyZWlyIDwtIGZ1bmN0aW9uKHJlc19hdmVyYWdlZCl7DQogICAgbmYyIDwtIDANCiAgICBpZiAoTCAlJSAyKSB7DQogICAgICBuZjIgPC0gKEwgKyAxKSAvIDIgLSAxDQogICAgfSBlbHNlIHsNCiAgICAgIG5mMiA8LSBMIC8gMiAtIDENCiAgICB9DQogICAgbmZ0IDwtIG5mMiArIGFicygoTCAlJSAyKSAtIDIpDQogICAgDQogICAgWiA8LSBtYXRyaXgoMCwgbmNvbCA9IG5mdCwgbnJvdyA9IG4pDQogICAgDQogICAgIyBwcmludChaIHw+IGRpbSgpKQ0KICAgICMgcHJpbnQocmVzX2F2ZXJhZ2VkIHw+IGRpbSgpKQ0KICAgIA0KICAgIFpbLCAxXSA8LSByZXNfYXZlcmFnZWRbMSwgXQ0KICAgIGZvciAoayBpbiAxOm5mMikgew0KICAgICAgWlssIGsgKyAxXSA8LSByZXNfYXZlcmFnZWRbayArIDEsIF0gKyByZXNfYXZlcmFnZWRbTCArIDIgLSAoayArIDEpLCBdDQogICAgfQ0KICAgIGlmIChMICUlIDIgIT0gMCkgew0KICAgICAgWlssIG5mdF0gPC0gcmVzX2F2ZXJhZ2VkW25mdCwgXQ0KICAgIH0NCiAgICANCiAgICANCiAgICByZXR1cm4obGlzdCgNCiAgICAgIHRfc2VyaWVzID0gWiwNCiAgICAgIGZyZXEgPSAoMDpkaW0oWilbMl0pL0wNCiAgICApKQ0KICB9DQoNCg0KICBycyA8LSBncm91cF9ieV9lbGVtZW50YXJ5X2ZyZXFfZm91cmVpcihhdnIpDQogIHJldHVybihycykNCn0NCg0KYGBgDQoNCmBgYHtyfQ0KZGF0YV9zbGljZSA8LSAxOjUzNw0KZGF0ZXNfc2xpY2UgPC0gZGF0ZXNbZGF0YV9zbGljZV0NCklQX3ZhbHVlc19zbGljZSA8LSBJUF92YWx1ZXNbZGF0YV9zbGljZV0NCmVwcyA8LSAxLzE5Mw0KDQoNCmMgPC0gY2lyY3VsYW50X1NTQShJUF92YWx1ZXNfc2xpY2UsIEwgPSAxOTIsIGV4dGVuZF9mbGFnID0gRkFMU0UpDQpyIDwtIGMkdF9zZXJpZXMNCg0KY19mdCA8LSBjaXNzYV9saWtlX2ZvdXJpZXJfdHJhbnNmb3JtKElQX3ZhbHVlc19zbGljZSwgTCA9IDE5MikNCnJfZnQgPC0gY19mdCR0X3Nlcmllcw0KDQpmb3IgKGkgaW4gMTpkaW0ocilbMl0pew0KICBwbG90KGRhdGFfc2xpY2UsIHJfZnRbLCBpXSwgY29sPSAicmVkIiwgdHlwZSA9ICJsIiwgbHdkID0gMikNCiAgbGluZXMoZGF0YV9zbGljZSwgclssIGldKQ0KfQ0KYGBgDQoNCiMjIyDQodGA0LDQstC90LXQvdC40LUg0YDQsNC30LvQvtC20LXQvdC40Lkg0LLRgdC10LPQviDQstGA0LXQvNC10L3QvdC+0LPQviDRgNGP0LTQsCDRh9C10YDQtdC3INC80LXRgtC+0LQg0KTRg9GA0YzQtSwgU1NBLCBhdXRvX1NTQSwgQ2lTU0Eg0LggQ2lTU0Eg0YEg0YDQsNGB0YjQuNGA0LXQvdC40LXQvCDRgNGP0LTQsA0KDQpgYGB7cn0NCnJlY29uc3RydWN0X2ZmdCA8LSBmdW5jdGlvbih4X2luaXQsIHlfaW5pdCwgZXh0ZW5kX2ZsYWcgPSBGQUxTRSkgew0KICAgIHggPC0geF9pbml0DQogICAgeSA8LSB5X2luaXQNCiAgICBOIDwtIGxlbmd0aCh5X2luaXQpDQogICAgSCA8LSAwDQogICAgaWYgKGV4dGVuZF9mbGFnID09IFRSVUUpew0KICAgICAgSCA8LSBsZW5ndGgoeSkgJS8lIDINCiAgICAgIHkgPC0gZXh0ZW5kKHksIEgpDQogICAgICB4IDwtIDA6KGxlbmd0aCh5KSAtIDEpDQogICAgfQ0KICAgIA0KICAgIGZyZXF1ZW5jaWVzIDwtICgwOihsZW5ndGgoeCktMSkpIC8gbGVuZ3RoKHgpDQogICAgZmZ0X3kgPC0gZmZ0KHkpDQogICAgDQogICAgYW1wbGl0dWRlcyA8LSBNb2QoZmZ0X3kpDQogICAgcGhhc2VzIDwtIEFyZyhmZnRfeSkNCiAgICANCiAgICByZWNvbnN0cnVjdGVkIDwtIG1hdHJpeCgwLCBsZW5ndGgoYW1wbGl0dWRlcyksIGxlbmd0aCh4KSkNCiAgICBuIDwtIGxlbmd0aChhbXBsaXR1ZGVzKQ0KICAgIEwgPC0gbg0KICAgIGZvciAoaSBpbiAxOihsZW5ndGgoYW1wbGl0dWRlcykpKSB7DQogICAgICByZWNvbnN0cnVjdGVkW2ksIF0gPC0NCiAgICAgICAgYW1wbGl0dWRlc1tpXSAqIA0KICAgICAgICBjb3MoMiAqIHBpICogZnJlcXVlbmNpZXNbaV0gKiAoeCkgKyBwaGFzZXNbaV0pIC8NCiAgICAgICAgbg0KICAgIH0NCiAgICANCiAgICANCiAgICANCiAgDQogICAgZ3JvdXBfYnlfZWxlbWVudGFyeV9mcmVxX2ZvdXJlaXIgPC0gZnVuY3Rpb24ocmVzX2F2ZXJhZ2VkKXsNCiAgICAgIG5mMiA8LSAwDQogICAgICBpZiAoTCAlJSAyKSB7DQogICAgICAgIG5mMiA8LSAoTCArIDEpIC8gMiAtIDENCiAgICAgIH0gZWxzZSB7DQogICAgICAgIG5mMiA8LSBMIC8gMiAtIDENCiAgICAgIH0NCiAgICAgIG5mdCA8LSBuZjIgKyBhYnMoKEwgJSUgMikgLSAyKQ0KICAgICAgDQogICAgICBaIDwtIG1hdHJpeCgwLCBuY29sID0gbmZ0LCBucm93ID0gbikNCiAgICAgIA0KICAgICAgIyBwcmludChaIHw+IGRpbSgpKQ0KICAgICAgIyBwcmludChyZXNfYXZlcmFnZWQgfD4gZGltKCkpDQogICAgICANCiAgICAgIFpbLCAxXSA8LSByZXNfYXZlcmFnZWRbMSwgXQ0KICAgICAgZm9yIChrIGluIDE6bmYyKSB7DQogICAgICAgIFpbLCBrICsgMV0gPC0gcmVzX2F2ZXJhZ2VkW2sgKyAxLCBdICsgcmVzX2F2ZXJhZ2VkW0wgKyAyIC0gKGsgKyAxKSwgXQ0KICAgICAgfQ0KICAgICAgaWYgKEwgJSUgMiAhPSAwKSB7DQogICAgICAgIFpbLCBuZnRdIDwtIHJlc19hdmVyYWdlZFtuZnQsIF0NCiAgICAgIH0NCiAgICAgIA0KICAgICAgDQogICAgICByZXR1cm4obGlzdCgNCiAgICAgICAgdF9zZXJpZXMgPSBaWyhIKzEpOihOK0gpLCBdLA0KICAgICAgICBmcmVxID0gKDA6KGRpbShaKVsyXS0xKSkvTA0KICAgICAgKSkNCiAgICB9DQogIA0KICANCiAgICBycyA8LSBncm91cF9ieV9lbGVtZW50YXJ5X2ZyZXFfZm91cmVpcihyZWNvbnN0cnVjdGVkKQ0KICAgIA0KICAgIA0KICAgIHJldHVybihsaXN0KA0KICAgICAgdF9zZXJpZXMgPSBycyR0X3NlcmllcywNCiAgICAgIGZyZXEgPSBycyRmcmVxDQogICAgICApKQ0KICB9DQpgYGANCg0KIyMjIyDQmNC00LXQsNC70YzQvdGL0Lkg0YHQu9GD0YfQsNC5INC00LvRjyBDaVNTQSDQuCBGb3VyaWVyDQoNCmBgYHtyfQ0KbiA8LSA5NioyDQpMIDwtIDk2DQp4IDwtIDA6KG4tMSkNCnkxIDwtIHNpbigyKnBpLzEyICogeCkNCnkyIDwtIGNvcygyKnBpLzMgKiB4KS8yDQp5IDwtIHkxICsgeTINClggPC0gaGFua2VsKHksIEwgPSBMKQ0KZXBzIDwtIDEvKG4rMSkNCg0Kc19zc2EgPC0gc3NhKHlbMToobi0xKV0sIEwpDQpyX3NzYSA8LSByZWNvbnN0cnVjdChzX3NzYSwgZ3JvdXBzID0gbGlzdCgNCiAgRjEgPSBjKDEsIDIpLA0KICBGMiA9IGMoMywgNCkNCikpDQojIHJfc3NhIDwtIHJlY29uc3RydWN0KHNfc3NhLCBncm91cHM9bGlzdCgNCiMgICBzZXNvbmFsX3NpbiA9IGMoMSwgMiksDQojICAgc2Vzb25hbF9jb3MgPSBjKDMsIDQpDQojICkpDQojIHBsb3QoeCwgcl9zc2EkRjEsIHR5cGU9ImwiKQ0KIyBwbG90KHgsIHJfc3NhJEYyLCB0eXBlPSAibCIpDQojIHBsb3Qod2NvcihzX3NzYSwgZ3JvdXBzID0gMToxMCksIHNjYWxlcyA9IGxpc3QoYXQgPSBjKDEwLCAyMCwgMzApKSkNCmVfc3NhIDwtIGVvc3NhX25ldyhzX3NzYSwgbmVzdGVkLmdyb3VwcyA9IGxpc3QoMTo0KSwgY2x1c3RfdHlwZSA9ICJkaXN0YW5jZSIpDQpnX3Nlc29uYWxfZSA8LSBncm91cGluZy5hdXRvKGVfc3NhLCBiYXNlID0gImVpZ2VuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgZnJlcS5iaW5zID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLA0KICAgICAgICAgICAgICAgICAgICAgICB0aHJlc2hvbGQgPSAwLjUpDQpyX3NzYV9lIDwtIHJlY29uc3RydWN0KGVfc3NhLCBncm91cHM9Z19zZXNvbmFsX2UpDQojIHBsb3QoeCwgcl9zc2FfZSRzZXNvbmFsX3NpbikNCiMgcGxvdCh4LCByX3NzYV9lJHNlc29uYWxfY29zKQ0KDQoNCg0Kcl9mZnQgPC0gcmVjb25zdHJ1Y3RfZmZ0KHgsIHkpDQpyX2ZmdF9ncm91cGVkIDwtIGdyb3VwaW5nX2Npc3NhKHJfZmZ0LA0KICAgICAgICAgICAgICAgICAgICBncm91cHMgPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICkkdF9zZXJpZXMNCg0Kcl9mZnRfZXh0ZW5kZWQgPC0gcmVjb25zdHJ1Y3RfZmZ0KHgsIHksIFRSVUUpDQpyX2ZmdF9ncm91cGVkX2V4dGVuZGVkIDwtIGdyb3VwaW5nX2Npc3NhKHJfZmZ0X2V4dGVuZGVkLA0KICAgICAgICAgICAgICAgICAgICBncm91cHMgPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICkkdF9zZXJpZXMNCg0KIyByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luIHw+IGxlbmd0aCgpDQoNCiMgcGxvdCh4LCByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luKQ0KIyBwbG90KHgsIHJfZmZ0X2dyb3VwZWQkc2Vzb25hbF9jb3MpDQojIHBsb3QoeCwgcl9mZnRfZ3JvdXBlZCRyZXNpZHVhbHMpDQoNCg0Kcl9jaXNzYSA8LSBjaXJjdWxhbnRfU1NBKHksIEwpDQpyX2Npc3NhX2dyb3VwZWQgPC0gZ3JvdXBpbmdfY2lzc2Eocl9jaXNzYSwNCiAgICAgICAgICAgICAgICAgICAgZ3JvdXBzID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICApJHRfc2VyaWVzDQoNCg0Kcl9jaXNzYV9leHQgPC0gY2lyY3VsYW50X1NTQSh5LCBMLCBleHRlbmRfZmxhZyA9IFRSVUUpDQpyX2Npc3NhX2dyb3VwZWRfZXh0IDwtIGdyb3VwaW5nX2Npc3NhKHJfY2lzc2FfZXh0LA0KICAgICAgICAgICAgICAgICAgICBncm91cHMgPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICkkdF9zZXJpZXMNCg0KIyBwbG90KHgsIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX3NpbikNCiMgcGxvdCh4LCByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9jb3MpDQojIHBsb3QoeCwgcl9jaXNzYV9ncm91cGVkJHJlc2lkdWFscykNCg0KbGlicmFyeSh4dGFibGUpDQoNCiMg0KjQsNCzIDI6INCh0L7Qt9C00LDQvdC40LUg0L/RgNC40LzQtdGA0LAg0LTQsNC90L3Ri9GFDQpkYXRhIDwtIGRhdGEuZnJhbWUoDQogINCc0LXRgtC+0LQgPSBjKCJTU0EiLCAiU1NBIEVPU1NBIiwiRm91cmllciIsICJDaVNTQSIsICJDaVNTQSBleHRlbmRlZCIsICJGb3VyaWVyIGV4dGVuZGVkIiksDQogIHNpbl9lcnIgPSBjICgxLCAyMCwgMjAsIDEsIDEsIDEpLA0KICBjb3NfZXJyID0gYygxLCAxLCAxLCAxLCAxLCAxKSwNCiAgYWxsX2VyciA9IGMoMSwgMSwgMSwgMSwgMSwgMSkNCikNCg0KZGF0YSRzaW5fZXJyWzFdIDwtIG1zZSh5MVsxOihuLTEpXSwgcl9zc2EkRjEpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKSANCmRhdGEkY29zX2VyclsxXSA8LSBtc2UoeTJbMToobi0xKV0sIHJfc3NhJEYyKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2VyclsxXSA8LSBtc2UoeTFbMToobi0xKV0gKyB5MlsxOihuLTEpXSwgcl9zc2EkRjEgKyByX3NzYSRGMikgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCmRhdGEkY29zX2VyclsyXSA8LSBtc2UoeTFbMToobi0xKV0sIHJfc3NhX2Ukc2Vzb25hbF9zaW4pIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzJdIDwtIG1zZSh5MlsxOihuLTEpXSwgcl9zc2FfZSRzZXNvbmFsX2NvcykgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbMl0gPC0gbXNlKHkxWzE6KG4tMSldICsgeTJbMToobi0xKV0sDQogICAgICAgICAgICAgICAgICAgICAgIHJfc3NhX2Ukc2Vzb25hbF9zaW4gKyByX3NzYV9lJHNlc29uYWxfY29zKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCg0KDQpkYXRhJGNvc19lcnJbM10gPC0gbXNlKHkxLCByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkc2luX2VyclszXSA8LSBtc2UoeTIsIHJfZmZ0X2dyb3VwZWQkc2Vzb25hbF9jb3MpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzNdIDwtIG1zZSh5MSArIHkyLA0KICAgICAgICAgICAgICAgICAgICAgICByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luICsgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX2Nvcw0KICAgICAgICAgICAgICAgICAgICAgICApIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCmRhdGEkY29zX2Vycls0XSA8LSBtc2UoeTEsIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX3NpbikgfD4gDQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzRdIDwtIG1zZSh5Miwgcl9jaXNzYV9ncm91cGVkJHNlc29uYWxfY29zKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbNF0gPC0gbXNlKHkxICsgeTIsDQogICAgICAgICAgICAgICAgICAgICAgIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX3NpbiArIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX2Nvcw0KICAgICAgICAgICAgICAgICAgICAgICApIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCmRhdGEkY29zX2Vycls1XSA8LSBtc2UoeTEsIHJfY2lzc2FfZ3JvdXBlZF9leHQkc2Vzb25hbF9zaW4pIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkc2luX2Vycls1XSA8LSBtc2UoeTIsIHJfY2lzc2FfZ3JvdXBlZF9leHQkc2Vzb25hbF9jb3MpIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2Vycls1XSA8LSBtc2UoeTEgKyB5MiwNCiAgICAgICAgICAgICAgICAgICAgICAgcl9jaXNzYV9ncm91cGVkX2V4dCRzZXNvbmFsX3NpbiArIHJfY2lzc2FfZ3JvdXBlZF9leHQkc2Vzb25hbF9jb3MNCiAgICAgICAgICAgICAgICAgICAgICAgKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCg0KDQpkYXRhJGNvc19lcnJbNl0gPC0gbXNlKHkxLCByX2ZmdF9ncm91cGVkX2V4dGVuZGVkJHNlc29uYWxfc2luKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkc2luX2Vycls2XSA8LSBtc2UoeTIsIHJfZmZ0X2dyb3VwZWRfZXh0ZW5kZWQkc2Vzb25hbF9jb3MpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzZdIDwtIG1zZSh5MSArIHkyLA0KICAgICAgICAgICAgICAgICAgICAgICByX2ZmdF9ncm91cGVkX2V4dGVuZGVkJHNlc29uYWxfc2luICsgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX2Nvcw0KICAgICAgICAgICAgICAgICAgICAgICApIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCnRhYmxlX2xhdGV4IDwtIHh0YWJsZShkYXRhLCBjYXB0aW9uID0gIkV4YW1wbGUgVGFibGUiKQ0KDQojINCo0LDQsyA0OiDQktGL0LLQvtC0INGC0LDQsdC70LjRhtGLINCyIExhVGVYINGE0LDQudC7DQpwcmludCh0YWJsZV9sYXRleCwgaW5jbHVkZS5yb3duYW1lcyA9IEZBTFNFKQ0KYGBgDQoNCiMjIyMg0JjQtNC10LDQu9GM0L3Ri9C5INGB0LvRg9GH0LDQuSDRgSDRiNGD0LzQvtC8DQoNCmBgYHtyfQ0KDQpkYXRhIDwtIGxpc3QoDQogINCc0LXRgtC+0LQgPSBjKCJTU0EiLCJTU0EgRU9TU0EiLCJGb3VyaWVyIiwgIkNpU1NBIiwgIkNpU1NBIGV4dGVuZGVkIiwgIkZvdXJpZXIgZXh0ZW5kZWQiKSwNCiAgc2luX2VyciA9IGxpc3QobGlzdCgpLCBsaXN0KCksIGxpc3QoKSwgbGlzdCgpLCBsaXN0KCksIGxpc3QoKSksDQogIGNvc19lcnIgPSBsaXN0KGxpc3QoKSwgbGlzdCgpLCBsaXN0KCksIGxpc3QoKSwgbGlzdCgpLCBsaXN0KCkpLA0KICBhbGxfZXJyID0gbGlzdChsaXN0KCksIGxpc3QoKSwgbGlzdCgpLCBsaXN0KCksIGxpc3QoKSwgbGlzdCgpKQ0KKQ0KDQpmb3IgKGkgaW4gMToxMDApew0KICBzZXQuc2VlZChpKQ0KICANCiAgbiA8LSA5NioyDQogIEwgPC0gOTYNCiAgeCA8LSAwOihuLTEpDQogIHkxIDwtIHNpbigyKnBpLzEyICogeCkNCiAgeTIgPC0gY29zKDIqcGkvMyAqIHgpLzINCiAgeSA8LSB5MSArIHkyICsgcm5vcm0obiwgMCwgMC4xKQ0KICBYIDwtIGhhbmtlbCh5LCBMID0gTCkNCiAgZXBzIDwtIDEvKG4rMSkNCiAgDQogIHNfc3NhIDwtIHNzYSh5WzE6KG4tMSldLCBMKQ0KICByX3NzYSA8LSByZWNvbnN0cnVjdChzX3NzYSwgZ3JvdXBzID0gbGlzdCgNCiAgICBGMSA9IGMoMSwgMiksDQogICAgRjIgPSBjKDMsIDQpDQogICkpDQogICMgcl9zc2EgPC0gcmVjb25zdHJ1Y3Qoc19zc2EsIGdyb3Vwcz1saXN0KA0KICAjICAgc2Vzb25hbF9zaW4gPSBjKDEsIDIpLA0KICAjICAgc2Vzb25hbF9jb3MgPSBjKDMsIDQpDQogICMgKSkNCiAgIyBwbG90KHhbMToobi0xKV0sIHJfc3NhJEYxLCB0eXBlID0gImwiKQ0KICAjIHBsb3QoeFsxOihuLTEpXSwgcl9zc2EkRjIsIHR5cGUgPSAibCIpDQogICMgcGxvdCh3Y29yKHNfc3NhLCBncm91cHMgPSAxOjEwKSwgc2NhbGVzID0gbGlzdChhdCA9IGMoMTAsIDIwLCAzMCkpKQ0KICBlX3NzYSA8LSBlb3NzYV9uZXcoc19zc2EsIG5lc3RlZC5ncm91cHMgPSBsaXN0KDE6NCksIGNsdXN0X3R5cGUgPSAiZGlzdGFuY2UiKQ0KICBnX3Nlc29uYWxfZSA8LSBncm91cGluZy5hdXRvKGVfc3NhLCBiYXNlID0gImVpZ2VuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICBmcmVxLmJpbnMgPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9zaW4gPSBjKDEvMTItZXBzLCAxLzEyK2VwcyksDQogICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksDQogICAgICAgICAgICAgICAgICAgICAgICAgdGhyZXNob2xkID0gMC41KQ0KICByX3NzYV9lIDwtIHJlY29uc3RydWN0KGVfc3NhLCBncm91cHM9Z19zZXNvbmFsX2UpDQogICMgcGxvdCh4LCByX3NzYV9lJHNlc29uYWxfc2luKQ0KICAjIHBsb3QoeCwgcl9zc2FfZSRzZXNvbmFsX2NvcykNCiAgDQogIA0KICANCiAgcl9mZnQgPC0gcmVjb25zdHJ1Y3RfZmZ0KHgsIHkpDQogIHJfZmZ0X2dyb3VwZWQgPC0gZ3JvdXBpbmdfY2lzc2Eocl9mZnQsDQogICAgICAgICAgICAgICAgICAgICAgZ3JvdXBzID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9jb3MgPSBjKDEvMy1lcHMsIDEvMytlcHMpDQogICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICAgICkkdF9zZXJpZXMNCiAgDQogIHJfZmZ0X2V4dGVuZGVkIDwtIHJlY29uc3RydWN0X2ZmdCh4LCB5LCBUUlVFKQ0KICByX2ZmdF9ncm91cGVkX2V4dGVuZGVkIDwtIGdyb3VwaW5nX2Npc3NhKHJfZmZ0X2V4dGVuZGVkLA0KICAgICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICAgICkNCiAgICAgICAgICAgICAgICAgICAgICApJHRfc2VyaWVzDQogIA0KICAjIHJfZmZ0X2dyb3VwZWQkc2Vzb25hbF9zaW4gfD4gbGVuZ3RoKCkNCiAgDQogICMgcGxvdCh4LCByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luKQ0KICAjIHBsb3QoeCwgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX2NvcykNCiAgIyBwbG90KHgsIHJfZmZ0X2dyb3VwZWQkcmVzaWR1YWxzKQ0KICANCiAgDQogIHJfY2lzc2EgPC0gY2lyY3VsYW50X1NTQSh5LCBMKQ0KICByX2Npc3NhX2dyb3VwZWQgPC0gZ3JvdXBpbmdfY2lzc2Eocl9jaXNzYSwNCiAgICAgICAgICAgICAgICAgICAgICBncm91cHMgPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9zaW4gPSBjKDEvMTItZXBzLCAxLzEyK2VwcyksDQogICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgKSR0X3Nlcmllcw0KICANCiAgDQogIHJfY2lzc2FfZXh0IDwtIGNpcmN1bGFudF9TU0EoeSwgTCwgZXh0ZW5kX2ZsYWcgPSBUUlVFKQ0KICByX2Npc3NhX2dyb3VwZWRfZXh0IDwtIGdyb3VwaW5nX2Npc3NhKHJfY2lzc2FfZXh0LA0KICAgICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICAgICkNCiAgICAgICAgICAgICAgICAgICAgICApJHRfc2VyaWVzDQogIGRhdGEkY29zX2VycltbMV1dW1tpXV0gPC0gDQogICAgbWluKG1zZSh5MVsxOihuLTEpXSwgcl9zc2EkRjEpLCBtc2UoeTFbMToobi0xKV0sIHJfc3NhJEYyKSkNCiAgZGF0YSRzaW5fZXJyW1sxXV1bW2ldXSA8LQ0KICAgIG1pbihtc2UoeTJbMToobi0xKV0sIHJfc3NhJEYxKSwgbXNlKHkyWzE6KG4tMSldLCByX3NzYSRGMikpDQogIGRhdGEkYWxsX2VycltbMV1dW1tpXV0gPC0NCiAgICBtaW4obXNlKHkxWzE6KG4tMSldK3kyWzE6KG4tMSldLCByX3NzYSRGMSsgcl9zc2EkRjIpKQ0KICANCiAgZGF0YSRjb3NfZXJyW1syXV1bW2ldXSA8LSBtc2UoeTFbMToobi0xKV0sIHJfc3NhX2Ukc2Vzb25hbF9zaW4pDQogIGRhdGEkc2luX2VycltbMl1dW1tpXV0gPC0gbXNlKHkyWzE6KG4tMSldLCByX3NzYV9lJHNlc29uYWxfY29zKQ0KICBkYXRhJGFsbF9lcnJbWzJdXVtbaV1dIDwtIG1zZSh5MVsxOihuLTEpXSsgeTJbMToobi0xKV0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJfc3NhX2Ukc2Vzb25hbF9zaW4gKyByX3NzYV9lJHNlc29uYWxfY29zKQ0KICANCiAgDQogIGRhdGEkY29zX2VycltbM11dW1tpXV0gPC0gbXNlKHkxLCByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luKQ0KICBkYXRhJHNpbl9lcnJbWzNdXVtbaV1dIDwtIG1zZSh5Miwgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX2NvcykNCiAgZGF0YSRhbGxfZXJyW1szXV1bW2ldXSA8LSBtc2UoeTEgKyB5MiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX2NvcyArICByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luKQ0KICANCiAgDQogIGRhdGEkY29zX2VycltbNF1dW1tpXV0gPC0gbXNlKHkxLCByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9zaW4pDQogIGRhdGEkc2luX2VycltbNF1dW1tpXV0gPC0gbXNlKHkyLCByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9jb3MpDQogIGRhdGEkYWxsX2VycltbNF1dW1tpXV0gPC0gbXNlKHkxICsgeTIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX3NpbiArICByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9jb3MNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICANCiAgZGF0YSRjb3NfZXJyW1s1XV1bW2ldXSA8LSBtc2UoeTEsIHJfY2lzc2FfZ3JvdXBlZF9leHQkc2Vzb25hbF9zaW4pDQogIGRhdGEkc2luX2VycltbNV1dW1tpXV0gPC0gbXNlKHkyLCByX2Npc3NhX2dyb3VwZWRfZXh0JHNlc29uYWxfY29zKQ0KICBkYXRhJGFsbF9lcnJbWzVdXVtbaV1dIDwtIG1zZSh5MSArIHkyLA0KICAgICAgICAgICAgICAgICAgICAgICAgICByX2Npc3NhX2dyb3VwZWRfZXh0JHNlc29uYWxfc2luICsgcl9jaXNzYV9ncm91cGVkX2V4dCRzZXNvbmFsX2Nvcw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogIA0KICBkYXRhJGNvc19lcnJbWzZdXVtbaV1dIDwtIG1zZSh5MSwgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX3NpbikNCiAgZGF0YSRzaW5fZXJyW1s2XV1bW2ldXSA8LSBtc2UoeTIsIHJfZmZ0X2dyb3VwZWRfZXh0ZW5kZWQkc2Vzb25hbF9jb3MpDQogIGRhdGEkYWxsX2VycltbNl1dW1tpXV0gPC0gbXNlKHkxICsgeTIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJfZmZ0X2dyb3VwZWRfZXh0ZW5kZWQkc2Vzb25hbF9zaW4gKyByX2ZmdF9ncm91cGVkX2V4dGVuZGVkJHNlc29uYWxfY29zDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkNCn0NCmxpYnJhcnkoeHRhYmxlKQ0KDQojINCo0LDQsyAyOiDQodC+0LfQtNCw0L3QuNC1INC/0YDQuNC80LXRgNCwINC00LDQvdC90YvRhQ0KZGF0YV9wcmV2IDwtIGRhdGENCg0KZGF0YSA8LSBkYXRhLmZyYW1lKA0KICDQnNC10YLQvtC0ID0gYygiU1NBIiwgIlNTQSBFT1NTQSIsIkZvdXJpZXIiLCAiQ2lTU0EiLCAiQ2lTU0EgZXh0ZW5kZWQiLCAiRm91cmllciBleHRlbmRlZCIpLA0KICBzaW5fZXJyID0gYygwLCAwLCAwLCAwLCAwLCAwKSwNCiAgY29zX2VyciA9IGMoMCwgMCwgMCwgMCwgMCwgMCksDQogIGFsbF9lcnIgPSBjKDAsIDAsIDAsIDAsIDAsIDApDQopDQoNCmRhdGEkY29zX2VyclsxXSA8LSBtZWFuKGRhdGFfcHJldiRjb3NfZXJyW1sxXV0gfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzFdIDwtIG1lYW4oZGF0YV9wcmV2JHNpbl9lcnJbWzFdXXw+IHVubGlzdCgpKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2VyclsxXSA8LSBtZWFuKGRhdGFfcHJldiRhbGxfZXJyW1sxXV18PiB1bmxpc3QoKSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCmRhdGEkY29zX2VyclsyXSA8LSBtZWFuKGRhdGFfcHJldiRjb3NfZXJyW1syXV0gfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzJdIDwtIG1lYW4oZGF0YV9wcmV2JHNpbl9lcnJbWzJdXXw+IHVubGlzdCgpKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2VyclsyXSA8LSBtZWFuKGRhdGFfcHJldiRhbGxfZXJyW1syXV18PiB1bmxpc3QoKSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCg0KZGF0YSRjb3NfZXJyWzNdIDwtIG1lYW4oZGF0YV9wcmV2JGNvc19lcnJbWzNdXXw+IHVubGlzdCgpKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkc2luX2VyclszXSA8LSBtZWFuKGRhdGFfcHJldiRzaW5fZXJyW1szXV18PiB1bmxpc3QoKSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbM10gPC0gbWVhbihkYXRhX3ByZXYkYWxsX2VycltbM11dfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCmRhdGEkY29zX2Vycls0XSA8LSBtZWFuKGRhdGFfcHJldiRjb3NfZXJyW1s0XV18PiB1bmxpc3QoKSkgfD4gDQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzRdIDwtIG1lYW4oZGF0YV9wcmV2JHNpbl9lcnJbWzRdXXw+IHVubGlzdCgpKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbNF0gPC0gbWVhbihkYXRhX3ByZXYkYWxsX2VycltbNF1dfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCmRhdGEkY29zX2Vycls1XSA8LSBtZWFuKGRhdGFfcHJldiRjb3NfZXJyW1s1XV18PiB1bmxpc3QoKSkgfD4gDQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzVdIDwtIG1lYW4oZGF0YV9wcmV2JHNpbl9lcnJbWzVdXXw+IHVubGlzdCgpKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbNV0gPC0gbWVhbihkYXRhX3ByZXYkYWxsX2VycltbNV1dfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQpkYXRhJGNvc19lcnJbNl0gPC0gbWVhbihkYXRhX3ByZXYkY29zX2VycltbNl1dfD4gdW5saXN0KCkpIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkc2luX2Vycls2XSA8LSBtZWFuKGRhdGFfcHJldiRzaW5fZXJyW1s2XV18PiB1bmxpc3QoKSkgfD4gDQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzZdIDwtIG1lYW4oZGF0YV9wcmV2JGFsbF9lcnJbWzZdXXw+IHVubGlzdCgpKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCg0KDQpgYGANCg0KYGBge3J9DQpmb3IgKGkgaW4gMTo2KXsNCiAgZm9yIChqIGluIChpKTo2KXsNCiAgICB4IDwtIGRhdGFfcHJldiRjb3NfZXJyW1tpXV0gfD4gdW5saXN0KCkNCiAgICB5IDwtIGRhdGFfcHJldiRjb3NfZXJyW1tqXV0gfD4gdW5saXN0KCkNCiAgICB0X3Rlc3RfcmVzdWx0IDwtIHQudGVzdCh4LCB5LCBwYWlyZWQgPSBUUlVFKQ0KICAgIHByaW50KHBhc3RlKCJjb3MsICIsIGRhdGEk0JzQtdGC0L7QtFtpXSwgIiAiLCBkYXRhJNCc0LXRgtC+0LRbal0sICIsIHAtdmFsID0gIiwgdF90ZXN0X3Jlc3VsdCRwLnZhbHVlKSkNCiAgfQ0KfQ0KDQpmb3IgKGkgaW4gMTo2KXsNCiAgZm9yIChqIGluIChpKTo2KXsNCiAgICB4IDwtIGRhdGFfcHJldiRzaW5fZXJyW1tpXV0gfD4gdW5saXN0KCkNCiAgICB5IDwtIGRhdGFfcHJldiRzaW5fZXJyW1tqXV0gfD4gdW5saXN0KCkNCiAgICB0X3Rlc3RfcmVzdWx0IDwtIHQudGVzdCh4LCB5LCBwYWlyZWQgPSBUUlVFKQ0KICAgIHByaW50KHBhc3RlKCJzaW4sICIsIGRhdGEk0JzQtdGC0L7QtFtpXSwgIiAiLCBkYXRhJNCc0LXRgtC+0LRbal0sICIsIHAtdmFsID0gIiwgdF90ZXN0X3Jlc3VsdCRwLnZhbHVlKSkNCiAgfQ0KfQ0KDQpmb3IgKGkgaW4gMTo2KXsNCiAgZm9yIChqIGluIChpKTo2KXsNCiAgICB4IDwtIGRhdGFfcHJldiRhbGxfZXJyW1tpXV0gfD4gdW5saXN0KCkNCiAgICB5IDwtIGRhdGFfcHJldiRhbGxfZXJyW1tqXV0gfD4gdW5saXN0KCkNCiAgICB0X3Rlc3RfcmVzdWx0IDwtIHQudGVzdCh4LCB5LCBwYWlyZWQgPSBUUlVFKQ0KICAgIHByaW50KHBhc3RlKCJhbGxfZXJyLCAiLCBkYXRhJNCc0LXRgtC+0LRbaV0sICIgIiwgZGF0YSTQnNC10YLQvtC0W2pdLCAiLCBwLXZhbCA9ICIsIHRfdGVzdF9yZXN1bHQkcC52YWx1ZSkpDQogIH0NCn0NCg0KDQp0YWJsZV9sYXRleCA8LSB4dGFibGUoZGF0YSwgY2FwdGlvbiA9ICJFeGFtcGxlIFRhYmxlIikNCg0KIyDQqNCw0LMgNDog0JLRi9Cy0L7QtCDRgtCw0LHQu9C40YbRiyDQsiBMYVRlWCDRhNCw0LnQuw0KcHJpbnQodGFibGVfbGF0ZXgsIGluY2x1ZGUucm93bmFtZXMgPSBGQUxTRSkNCg0KIyBtZWFuKGRhdGFfcHJldiRzaW5fZXJyW1syXV0gfD4gdW5saXN0KCkpIHw+IHByaW50KCkNCiMgbWVhbihkYXRhX3ByZXYkc2luX2VycltbMV1dIHw+IHVubGlzdCgpKSB8PiBwcmludCgpDQpgYGANCg0KIyMjIyDQlNC+0LHQsNCy0LjQvCDQvdC10L/QtdGA0LjQvtC00LjRh9C90L7RgdGC0YwNCg0KYGBge3J9DQpuIDwtIDk2KjINCnggPC0gMDoobi0xKQ0KTCA8LSA5Ng0KeTEgPC0gc2luKDIqcGkvMTIgKiB4KQ0KeTIgPC0gY29zKDIqcGkvMyAqIHgpLzINCnkzIDwtIGV4cCh4LzEwMCkgKyAxDQp5IDwtIHkxICsgeTIgKyB5Mw0KZXBzIDwtIDEvKG4rMSkNCg0Kc19zc2EgPC0gc3NhKHlbMToobi0xKV0sIEwpDQpyX3NzYSA8LSByZWNvbnN0cnVjdChzX3NzYSwgZ3JvdXBzPWxpc3QoDQogIGUgPSBjKDEsIDYpLA0KICBzZXNvbmFsX3NpbiA9IGMoMiwgMyksDQogIHNlc29uYWxfY29zID0gYyg0LCA1KSwNCiAgYWxsID0gMTo2DQopKQ0KIyBwbG90KHhbMToobi0xKV0sIHJfc3NhJGUsIHR5cGUgPSAibCIpDQojIHBsb3QoeFsxOihuLTEpXSwgcl9zc2Ekc2Vzb25hbF9zaW4sIHR5cGUgPSAibCIpDQojIHBsb3QoeFsxOihuLTEpXSwgcl9zc2Ekc2Vzb25hbF9jb3MsIHR5cGUgPSAibCIpDQojIHBsb3Qod2NvcihzX3NzYSwgZ3JvdXBzID0gMToxMCksIHNjYWxlcyA9IGxpc3QoYXQgPSBjKDEwLCAyMCwgMzApKSkNCmVfc3NhIDwtIGVvc3NhX25ldyhzX3NzYSwgbmVzdGVkLmdyb3VwcyA9IGxpc3QoMTo2KSwgY2x1c3RfdHlwZSA9ICJkaXN0YW5jZSIpDQpnX3Nlc29uYWxfZSA8LSBncm91cGluZy5hdXRvKGVfc3NhLCBiYXNlID0gImVpZ2VuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgZnJlcS5iaW5zID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICAgICBlID0gYygwLCAxLzEyLWVwcy1lcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksDQogICAgICAgICAgICAgICAgICAgICAgIHRocmVzaG9sZCA9IDAuNSkNCnJfc3NhX2UgPC0gcmVjb25zdHJ1Y3QoZV9zc2EsIGdyb3Vwcz1nX3Nlc29uYWxfZSkNCiMgcGxvdCh4LCByX3NzYV9lJHNlc29uYWxfc2luKQ0KIyBwbG90KHgsIHJfc3NhX2Ukc2Vzb25hbF9jb3MpDQoNCg0KDQpyX2ZmdCA8LSByZWNvbnN0cnVjdF9mZnQoeCwgeSkNCnJfZmZ0X2dyb3VwZWQgPC0gZ3JvdXBpbmdfY2lzc2Eocl9mZnQsDQogICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgZSA9IGMoMCwgMS8xMi1lcHMtZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICApJHRfc2VyaWVzDQoNCnJfZmZ0X2V4dGVuZGVkIDwtIHJlY29uc3RydWN0X2ZmdCh4LCB5LCBUUlVFKQ0Kcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCA8LSBncm91cGluZ19jaXNzYShyX2ZmdF9leHRlbmRlZCwNCiAgICAgICAgICAgICAgICAgICAgZ3JvdXBzID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICBlID0gYygwLCAxLzEyLWVwcy1lcHMpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICkkdF9zZXJpZXMNCg0KIyByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luIHw+IGxlbmd0aCgpDQoNCiMgcGxvdCh4LCByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luKQ0KIyBwbG90KHgsIHJfZmZ0X2dyb3VwZWQkc2Vzb25hbF9jb3MpDQojIHBsb3QoeCwgcl9mZnRfZ3JvdXBlZCRyZXNpZHVhbHMpDQoNCg0Kcl9jaXNzYSA8LSBjaXJjdWxhbnRfU1NBKHksIEwpDQpyX2Npc3NhX2dyb3VwZWQgPC0gZ3JvdXBpbmdfY2lzc2Eocl9jaXNzYSwNCiAgICAgICAgICAgICAgICAgICAgZ3JvdXBzID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICBlID0gYygwLCAxLzEyLWVwcy1lcHMpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICkkdF9zZXJpZXMNCg0KDQpyX2Npc3NhX2V4dCA8LSBjaXJjdWxhbnRfU1NBKHksIEwsIGV4dGVuZF9mbGFnID0gVFJVRSkNCnJfY2lzc2FfZ3JvdXBlZF9leHQgPC0gZ3JvdXBpbmdfY2lzc2Eocl9jaXNzYV9leHQsDQogICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgZSA9IGMoMCwgMS8xMi1lcHMtZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICApJHRfc2VyaWVzDQoNCiMgcGxvdCh4LCByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9zaW4pDQojIHBsb3QoeCwgcl9jaXNzYV9ncm91cGVkJHNlc29uYWxfY29zKQ0KIyBwbG90KHgsIHJfY2lzc2FfZ3JvdXBlZCRyZXNpZHVhbHMpDQoNCmxpYnJhcnkoeHRhYmxlKQ0KDQojINCo0LDQsyAyOiDQodC+0LfQtNCw0L3QuNC1INC/0YDQuNC80LXRgNCwINC00LDQvdC90YvRhQ0KZGF0YSA8LSBkYXRhLmZyYW1lKA0KICDQnNC10YLQvtC0ID0gYygiU1NBIiwgIlNTQSBFT1NTQSIsIkZvdXJpZXIiLCAiQ2lTU0EiLCAiQ2lTU0EgZXh0ZW5kZWQiLCAiRm91cmllciBleHRlbmRlZCIpLA0KICBlX2VyciA9IGMoMSwgMSwgMSwgMSwgMSwgMSksDQogIHNpbl9lcnIgPSBjICgxLCAyMCwgMjAsIDEsIDEsIDEpLA0KICBjb3NfZXJyID0gYygxLCAxLCAxLCAxLCAxLCAxKSwNCiAgYWxsX2VyciA9IGMoMSwgMSwgMSwgMSwgMSwgMSkNCikNCg0KZGF0YSRjb3NfZXJyWzFdIDwtIG1zZSh5MVsxOihuLTEpXSwgcl9zc2Ekc2Vzb25hbF9zaW4pIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzFdIDwtIG1zZSh5MlsxOihuLTEpXSwgcl9zc2Ekc2Vzb25hbF9jb3MpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRlX2VyclsxXSA8LSBtc2UoeTNbMToobi0xKV0sIHJfc3NhJGUpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzFdIDwtIG1zZSh5MVsxOihuLTEpXSsgeTJbMToobi0xKV0gKyB5M1sxOihuLTEpXSwNCiAgICAgICAgICAgICAgICAgICAgIHJfc3NhJGFsbCkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCmRhdGEkY29zX2VyclsyXSA8LSBtc2UoeTFbMToobi0xKV0sIHJfc3NhX2Ukc2Vzb25hbF9zaW4pIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzJdIDwtIG1zZSh5MlsxOihuLTEpXSwgcl9zc2FfZSRzZXNvbmFsX2NvcykgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGVfZXJyWzJdIDwtIG1zZSh5M1sxOihuLTEpXSwgcl9zc2FfZSRlKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2VyclsyXSA8LSBtc2UoeTFbMToobi0xKV0rIHkyWzE6KG4tMSldICsgeTNbMToobi0xKV0sDQogICAgICAgICAgICAgICAgICAgICByX3NzYV9lJHNlc29uYWxfc2luICsgcl9zc2FfZSRzZXNvbmFsX2NvcyArIHJfc3NhX2UkZQ0KICAgICAgICAgICAgICAgICAgICAgICApIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCmRhdGEkY29zX2VyclszXSA8LSBtc2UoeTEsIHJfZmZ0X2dyb3VwZWQkc2Vzb25hbF9zaW4pIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzNdIDwtIG1zZSh5Miwgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX2NvcykgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGVfZXJyWzNdIDwtIG1zZSh5Mywgcl9mZnRfZ3JvdXBlZCRlKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2VyclszXSA8LSBtc2UoeTEgKyB5MiArIHkzLCANCiAgICAgICAgICAgICAgICAgICAgICAgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX3NpbiArIHJfZmZ0X2dyb3VwZWQkc2Vzb25hbF9jb3MgKyByX2ZmdF9ncm91cGVkJGUpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCmRhdGEkY29zX2Vycls0XSA8LSBtc2UoeTEsIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX3NpbikgfD4gDQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzRdIDwtIG1zZSh5Miwgcl9jaXNzYV9ncm91cGVkJHNlc29uYWxfY29zKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGVfZXJyWzRdIDwtIG1zZSh5Mywgcl9jaXNzYV9ncm91cGVkJGUpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzRdIDwtIG1zZSh5MSArIHkyICsgeTMsIA0KICAgICAgICAgICAgICAgICAgICAgICByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9zaW4gKyANCiAgICAgICAgICAgICAgICAgICAgICAgICByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9jb3MgKyANCiAgICAgICAgICAgICAgICAgICAgICAgICByX2Npc3NhX2dyb3VwZWQkZQ0KICAgICAgICAgICAgICAgICAgICAgICApIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQpkYXRhJGNvc19lcnJbNV0gPC0gbXNlKHkxLCByX2Npc3NhX2dyb3VwZWRfZXh0JHNlc29uYWxfc2luKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbNV0gPC0gbXNlKHkyLCByX2Npc3NhX2dyb3VwZWRfZXh0JHNlc29uYWxfY29zKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGVfZXJyWzVdIDwtIG1zZSh5Mywgcl9jaXNzYV9ncm91cGVkX2V4dCRlKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2Vycls1XSA8LSBtc2UoeTEgKyB5MiArIHkzLCANCiAgICAgICAgICAgICAgICAgICAgICAgcl9jaXNzYV9ncm91cGVkX2V4dCRzZXNvbmFsX3NpbiArIA0KICAgICAgICAgICAgICAgICAgICAgICAgIHJfY2lzc2FfZ3JvdXBlZF9leHQkc2Vzb25hbF9jb3MgKw0KICAgICAgICAgICAgICAgICAgICAgICAgICByX2Npc3NhX2dyb3VwZWRfZXh0JGUNCiAgICAgICAgICAgICAgICAgICAgICAgKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCg0KZGF0YSRjb3NfZXJyWzZdIDwtIG1zZSh5MSwgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX3NpbikgfD4gDQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzZdIDwtIG1zZSh5Miwgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX2NvcykgfD4gDQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRlX2Vycls2XSA8LSBtc2UoeTMsIHJfZmZ0X2dyb3VwZWRfZXh0ZW5kZWQkZSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbNl0gPC0gbXNlKHkxICsgeTIgKyB5MywgDQogICAgICAgICAgICAgICAgICAgICAgIHJfZmZ0X2dyb3VwZWRfZXh0ZW5kZWQkc2Vzb25hbF9zaW4gKw0KICAgICAgICAgICAgICAgICAgICAgICAgIHJfZmZ0X2dyb3VwZWRfZXh0ZW5kZWQkc2Vzb25hbF9jb3MgKw0KICAgICAgICAgICAgICAgICAgICAgICAgIHJfZmZ0X2dyb3VwZWRfZXh0ZW5kZWQkZQ0KICAgICAgICAgICAgICAgICAgICAgICApIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCg0KdGFibGVfbGF0ZXggPC0geHRhYmxlKGRhdGEsIGNhcHRpb24gPSAiRXhhbXBsZSBUYWJsZSIpDQoNCiMg0KjQsNCzIDQ6INCS0YvQstC+0LQg0YLQsNCx0LvQuNGG0Ysg0LIgTGFUZVgg0YTQsNC50LsNCnByaW50KHRhYmxlX2xhdGV4LCBpbmNsdWRlLnJvd25hbWVzID0gRkFMU0UpDQpgYGANCg0KIyMjIyDQndC10L/QtdGA0LjQvtC00LjRh9C90L7RgdGC0Ywg0YEg0YjRg9C80L7QvA0KDQpgYGB7cn0NCiMgZGF0YSA8LSBkYXRhLmZyYW1lKA0KIyAgINCc0LXRgtC+0LQgPSBjKCJGb3VyaWVyIiwgIkNpU1NBIiwgIkNpU1NBINGBINGA0LDRgdGI0LjRgNC10L3QuNC10Lwg0YDRj9C00LAiKSwNCiMgICBzaW5fZXJyID0gYyAoMjAsIDIwLCAyMCksDQojICAgY29zX2VyciA9IGMoMSwgMSwgMjApLA0KIyAgIGV4cF9lcnIgPSBjKDEsIDEsIDIwKQ0KIyApDQpkYXRhIDwtIGxpc3QoDQogINCc0LXRgtC+0LQgPSBjKCJTU0EiLCAiU1NBIEVPU1NBIiwiRm91cmllciIsICJDaVNTQSIsICJDaVNTQSBleHRlbmRlZCIsICJGb3VyaWVyIGV4dGVuZGVkIiksDQogIHNpbl9lcnIgPSBsaXN0KGxpc3QoKSwgbGlzdCgpLCBsaXN0KCksIGxpc3QoKSwgbGlzdCgpLCBsaXN0KCkpLA0KICBjb3NfZXJyID0gbGlzdChsaXN0KCksIGxpc3QoKSwgbGlzdCgpLCBsaXN0KCksIGxpc3QoKSwgbGlzdCgpKSwNCiAgZXhwX2VyciA9IGxpc3QobGlzdCgpLCBsaXN0KCksIGxpc3QoKSwgbGlzdCgpLCBsaXN0KCksIGxpc3QoKSksDQogIGFsbF9lcnIgPSBsaXN0KGxpc3QoKSwgbGlzdCgpLCBsaXN0KCksIGxpc3QoKSwgbGlzdCgpLCBsaXN0KCkpDQopDQoNCmZvciAoaSBpbiAxOjEwMCl7DQogIHNldC5zZWVkKGkpDQogIA0KICBuIDwtIDk2KjINCiAgeCA8LSAwOihuLTEpDQogIEwgPC0gOTYNCiAgeTEgPC0gc2luKDIqcGkvMTIgKiB4KQ0KICB5MiA8LSBjb3MoMipwaS8zICogeCkvMg0KICB5MyA8LSBleHAoeC8xMDApICsgMQ0KICB5IDwtIHkxICsgeTIgKyB5MyArIHJub3JtKG4sIDAsIDAuMSkNCiAgZXBzIDwtIDEvKG4rMSkNCiAgDQogIHNfc3NhIDwtIHNzYSh5WzE6KG4tMSldLCBMKQ0KICByX3NzYSA8LSByZWNvbnN0cnVjdChzX3NzYSwgZ3JvdXBzPWxpc3QoDQogICAgZSA9IDEsDQogICAgc2Vzb25hbF9zaW4gPSBjKDIsIDMpLA0KICAgIHNlc29uYWxfY29zID0gYyg0LCA1KQ0KICApKQ0KICANCiAgDQogIGVfc3NhIDwtIGVvc3NhX25ldyhzX3NzYSwgbmVzdGVkLmdyb3VwcyA9IGxpc3QoMTo3KSwgY2x1c3RfdHlwZSA9ICJkaXN0YW5jZSIpDQogIGdfc2Vzb25hbF9lIDwtIGdyb3VwaW5nLmF1dG8oZV9zc2EsIGJhc2UgPSAiZWlnZW4iLA0KICAgICAgICAgICAgICAgICAgICAgICAgIGZyZXEuYmlucyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgICAgICBlID0gYygwLCAxLzEyLWVwcy1lcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9zaW4gPSBjKDEvMTItZXBzLCAxLzEyK2VwcyksDQogICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksDQogICAgICAgICAgICAgICAgICAgICAgICAgdGhyZXNob2xkID0gMC41KQ0KICByX3NzYV9lIDwtIHJlY29uc3RydWN0KGVfc3NhLCBncm91cHM9Z19zZXNvbmFsX2UpDQogIA0KICANCiAgDQogIHJfZmZ0IDwtIHJlY29uc3RydWN0X2ZmdCh4LCB5KQ0KICByX2ZmdF9ncm91cGVkIDwtIGdyb3VwaW5nX2Npc3NhKHJfZmZ0LA0KICAgICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgICBlID0gYygwLCAxLzEyLWVwcy1lcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9zaW4gPSBjKDEvMTItZXBzLCAxLzEyK2VwcyksDQogICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgKSR0X3Nlcmllcw0KICANCiAgcl9mZnRfZXh0ZW5kZWQgPC0gcmVjb25zdHJ1Y3RfZmZ0KHgsIHksIFRSVUUpDQogIHJfZmZ0X2dyb3VwZWRfZXh0ZW5kZWQgPC0gZ3JvdXBpbmdfY2lzc2Eocl9mZnRfZXh0ZW5kZWQsDQogICAgICAgICAgICAgICAgICAgICAgZ3JvdXBzID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICAgIGUgPSBjKDAsIDEvMTItZXBzLWVwcyksDQogICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICAgICkNCiAgICAgICAgICAgICAgICAgICAgICApJHRfc2VyaWVzDQogIA0KICANCiAgcl9jaXNzYSA8LSBjaXJjdWxhbnRfU1NBKHksIEwpDQogIHJfY2lzc2FfZ3JvdXBlZCA8LSBncm91cGluZ19jaXNzYShyX2Npc3NhLA0KICAgICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgICBlID0gYygwLCAxLzEyLWVwcy1lcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9zaW4gPSBjKDEvMTItZXBzLCAxLzEyK2VwcyksDQogICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgKSR0X3Nlcmllcw0KICANCiAgDQogIHJfY2lzc2FfZXh0IDwtIGNpcmN1bGFudF9TU0EoeSwgTCwgZXh0ZW5kX2ZsYWcgPSBUUlVFKQ0KICByX2Npc3NhX2dyb3VwZWRfZXh0IDwtIGdyb3VwaW5nX2Npc3NhKHJfY2lzc2FfZXh0LA0KICAgICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgICBlID0gYygwLCAxLzEyLWVwcy1lcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9zaW4gPSBjKDEvMTItZXBzLCAxLzEyK2VwcyksDQogICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgKSR0X3Nlcmllcw0KICANCiAgDQogIA0KICBkYXRhJGNvc19lcnJbWzFdXVtbaV1dIDwtIG1zZSh5MVsxOihuLTEpXSwgcl9zc2Ekc2Vzb25hbF9zaW4pDQogIGRhdGEkc2luX2VycltbMV1dW1tpXV0gPC0gbXNlKHkyWzE6KG4tMSldLCByX3NzYSRzZXNvbmFsX2NvcykNCiAgZGF0YSRleHBfZXJyW1sxXV1bW2ldXSA8LSBtc2UoeTNbMToobi0xKV0sIHJfc3NhJGUpDQogIGRhdGEkYWxsX2VycltbMV1dW1tpXV0gPC0gbXNlKHkxWzE6KG4tMSldICsgeTJbMToobi0xKV0gKyB5M1sxOihuLTEpXSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcl9zc2Ekc2Vzb25hbF9zaW4rDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcl9zc2Ekc2Vzb25hbF9jb3MgKw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJfc3NhJGUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICANCiAgZGF0YSRjb3NfZXJyW1syXV1bW2ldXSA8LSBtc2UoeTFbMToobi0xKV0sIHJfc3NhX2Ukc2Vzb25hbF9zaW4pDQogIGRhdGEkc2luX2VycltbMl1dW1tpXV0gPC0gbXNlKHkyWzE6KG4tMSldLCByX3NzYV9lJHNlc29uYWxfY29zKQ0KICBkYXRhJGV4cF9lcnJbWzJdXVtbaV1dIDwtIG1zZSh5M1sxOihuLTEpXSwgcl9zc2FfZSRlKQ0KICBkYXRhJGFsbF9lcnJbWzJdXVtbaV1dIDwtIG1zZSh5MVsxOihuLTEpXSArIHkyWzE6KG4tMSldICsgeTNbMToobi0xKV0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJfc3NhX2Ukc2Vzb25hbF9zaW4rIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJfc3NhX2Ukc2Vzb25hbF9jb3MgKyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByX3NzYV9lJGUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICANCiAgDQogICMgcHJpbnQoZGF0YSRzaW5fZXJyW1syXV1bW2ldXSkNCiAgDQogIA0KICBkYXRhJGNvc19lcnJbWzNdXVtbaV1dIDwtIG1zZSh5MSwgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX3NpbikNCiAgZGF0YSRzaW5fZXJyW1szXV1bW2ldXSA8LSBtc2UoeTIsIHJfZmZ0X2dyb3VwZWQkc2Vzb25hbF9jb3MpDQogIGRhdGEkZXhwX2VycltbM11dW1tpXV0gPC0gbXNlKHkzLCByX2ZmdF9ncm91cGVkJGUpDQogIGRhdGEkYWxsX2VycltbM11dW1tpXV0gPC0gbXNlKHkxICsgeTIgKyB5MywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX3NpbiArDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX2NvcyArDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcl9mZnRfZ3JvdXBlZCRlDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkNCiAgDQogIA0KICBkYXRhJGNvc19lcnJbWzRdXVtbaV1dIDwtIG1zZSh5MSwgcl9jaXNzYV9ncm91cGVkJHNlc29uYWxfc2luKQ0KICBkYXRhJHNpbl9lcnJbWzRdXVtbaV1dIDwtIG1zZSh5Miwgcl9jaXNzYV9ncm91cGVkJHNlc29uYWxfY29zKQ0KICBkYXRhJGV4cF9lcnJbWzRdXVtbaV1dIDwtIG1zZSh5Mywgcl9jaXNzYV9ncm91cGVkJGUpDQogIGRhdGEkYWxsX2VycltbNF1dW1tpXV0gPC0gbXNlKHkxICsgeTIgKyB5MywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcl9jaXNzYV9ncm91cGVkJHNlc29uYWxfc2luICsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9jb3MgKw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJfY2lzc2FfZ3JvdXBlZCRlDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkNCiAgDQogIA0KICBkYXRhJGNvc19lcnJbWzVdXVtbaV1dIDwtIG1zZSh5MSwgcl9jaXNzYV9ncm91cGVkX2V4dCRzZXNvbmFsX3NpbikNCiAgZGF0YSRzaW5fZXJyW1s1XV1bW2ldXSA8LSBtc2UoeTIsIHJfY2lzc2FfZ3JvdXBlZF9leHQkc2Vzb25hbF9jb3MpDQogIGRhdGEkZXhwX2VycltbNV1dW1tpXV0gPC0gbXNlKHkzLCByX2Npc3NhX2dyb3VwZWRfZXh0JGUpDQogIGRhdGEkYWxsX2VycltbNV1dW1tpXV0gPC0gbXNlKHkxICsgeTIgKyB5MywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcl9jaXNzYV9ncm91cGVkX2V4dCRzZXNvbmFsX3NpbiArIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJfY2lzc2FfZ3JvdXBlZF9leHQkc2Vzb25hbF9jb3MgKw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJfY2lzc2FfZ3JvdXBlZF9leHQkZQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogIA0KICBkYXRhJGNvc19lcnJbWzZdXVtbaV1dIDwtIG1zZSh5MSwgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX3NpbikNCiAgZGF0YSRzaW5fZXJyW1s2XV1bW2ldXSA8LSBtc2UoeTIsIHJfZmZ0X2dyb3VwZWRfZXh0ZW5kZWQkc2Vzb25hbF9jb3MpDQogIGRhdGEkZXhwX2VycltbNl1dW1tpXV0gPC0gbXNlKHkzLCByX2ZmdF9ncm91cGVkX2V4dGVuZGVkJGUpDQogIGRhdGEkYWxsX2VycltbNl1dW1tpXV0gPC0gbXNlKHkxICsgeTIgKyB5MywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX3NpbiArDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX2NvcyArDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRlDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkNCn0NCmxpYnJhcnkoeHRhYmxlKQ0KIyBkYXRhJHNpbl9lcnJbWzJdXQ0KIyDQqNCw0LMgMjog0KHQvtC30LTQsNC90LjQtSDQv9GA0LjQvNC10YDQsCDQtNCw0L3QvdGL0YUNCmRhdGFfcHJldiA8LSBkYXRhDQpkYXRhIDwtIGRhdGEuZnJhbWUoDQogINCc0LXRgtC+0LQgPSBjKCJTU0EiLCAiU1NBIEVPU1NBIiwiRm91cmllciIsICJDaVNTQSIsICJDaVNTQSBleHRlbmRlZCIsICJGb3VyaWVyIGV4dGVuZGVkIiksDQogIGV4cF9lcnIgPSBjKDAsIDAsIDAsIDAsIDAsIDApLA0KICBzaW5fZXJyID0gYygwLCAwLCAwLCAwLCAwLCAwKSwNCiAgY29zX2VyciA9IGMoMCwgMCwgMCwgMCwgMCwgMCksDQogIGFsbF9lcnIgPSBjKDAsIDAsIDAsIDAsIDAsIDApDQopDQoNCmRhdGEkY29zX2VyclsxXSA8LSBtZWFuKGRhdGFfcHJldiRjb3NfZXJyW1sxXV0gfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzFdIDwtIG1lYW4oZGF0YV9wcmV2JHNpbl9lcnJbWzFdXXw+IHVubGlzdCgpKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkZXhwX2VyclsxXSA8LSBtZWFuKGRhdGFfcHJldiRleHBfZXJyW1sxXV18PiB1bmxpc3QoKSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbMV0gPC0gbWVhbihkYXRhX3ByZXYkYWxsX2VycltbMV1dfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCmRhdGEkY29zX2VyclsyXSA8LSBtZWFuKGRhdGFfcHJldiRjb3NfZXJyW1syXV18PiB1bmxpc3QoKSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbMl0gPC0gbWVhbihkYXRhX3ByZXYkc2luX2VycltbMl1dfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRleHBfZXJyWzJdIDwtIG1lYW4oZGF0YV9wcmV2JGV4cF9lcnJbWzJdXXw+IHVubGlzdCgpKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2VyclsyXSA8LSBtZWFuKGRhdGFfcHJldiRhbGxfZXJyW1syXV18PiB1bmxpc3QoKSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCg0KZGF0YSRjb3NfZXJyWzNdIDwtIG1lYW4oZGF0YV9wcmV2JGNvc19lcnJbWzNdXXw+IHVubGlzdCgpKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbM10gPC0gbWVhbihkYXRhX3ByZXYkc2luX2VycltbM11dfD4gdW5saXN0KCkpIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkZXhwX2VyclszXSA8LSBtZWFuKGRhdGFfcHJldiRleHBfZXJyW1szXV18PiB1bmxpc3QoKSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbM10gPC0gbWVhbihkYXRhX3ByZXYkYWxsX2VycltbM11dfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCmRhdGEkY29zX2Vycls0XSA8LSBtZWFuKGRhdGFfcHJldiRjb3NfZXJyW1s0XV18PiB1bmxpc3QoKSkgfD4gDQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzRdIDwtIG1lYW4oZGF0YV9wcmV2JHNpbl9lcnJbWzRdXXw+IHVubGlzdCgpKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGV4cF9lcnJbNF0gPC0gbWVhbihkYXRhX3ByZXYkZXhwX2VycltbNF1dfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzRdIDwtIG1lYW4oZGF0YV9wcmV2JGFsbF9lcnJbWzRdXXw+IHVubGlzdCgpKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCg0KZGF0YSRjb3NfZXJyWzVdIDwtIG1lYW4oZGF0YV9wcmV2JGNvc19lcnJbWzVdXXw+IHVubGlzdCgpKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbNV0gPC0gbWVhbihkYXRhX3ByZXYkc2luX2VycltbNV1dfD4gdW5saXN0KCkpIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkZXhwX2Vycls1XSA8LSBtZWFuKGRhdGFfcHJldiRleHBfZXJyW1s1XV18PiB1bmxpc3QoKSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbNV0gPC0gbWVhbihkYXRhX3ByZXYkYWxsX2VycltbNV1dfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQpkYXRhJGNvc19lcnJbNl0gPC0gbWVhbihkYXRhX3ByZXYkY29zX2VycltbNl1dfD4gdW5saXN0KCkpIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkc2luX2Vycls2XSA8LSBtZWFuKGRhdGFfcHJldiRzaW5fZXJyW1s2XV18PiB1bmxpc3QoKSkgfD4gDQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRleHBfZXJyWzZdIDwtIG1lYW4oZGF0YV9wcmV2JGV4cF9lcnJbWzZdXXw+IHVubGlzdCgpKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2Vycls2XSA8LSBtZWFuKGRhdGFfcHJldiRhbGxfZXJyW1s2XV18PiB1bmxpc3QoKSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCg0KYGBgDQoNCmBgYHtyfQ0KZm9yIChpIGluIDE6Nil7DQogIGZvciAoaiBpbiAoaSk6Nil7DQogICAgeCA8LSBkYXRhX3ByZXYkY29zX2VycltbaV1dIHw+IHVubGlzdCgpDQogICAgeSA8LSBkYXRhX3ByZXYkY29zX2Vycltbal1dIHw+IHVubGlzdCgpDQogICAgdF90ZXN0X3Jlc3VsdCA8LSB0LnRlc3QoeCwgeSwgcGFpcmVkID0gVFJVRSkNCiAgICBpZiAoIWlzLm5hKHRfdGVzdF9yZXN1bHQkcC52YWx1ZSkgJiB0X3Rlc3RfcmVzdWx0JHAudmFsdWUgPiAwLjA1KXsNCiAgICAgIHByaW50KHBhc3RlKCJjb3MsICIsIGRhdGEk0JzQtdGC0L7QtFtpXSwgIiAiLA0KICAgICAgICAgICAgICAgICAgZGF0YSTQnNC10YLQvtC0W2pdLCAiLCBwLXZhbCA9ICIsIHRfdGVzdF9yZXN1bHQkcC52YWx1ZSkpDQogICAgICB9DQogIH0NCn0NCg0KZm9yIChpIGluIDE6Nil7DQogIGZvciAoaiBpbiAoaSk6Nil7DQogICAgeCA8LSBkYXRhX3ByZXYkc2luX2VycltbaV1dIHw+IHVubGlzdCgpDQogICAgeSA8LSBkYXRhX3ByZXYkc2luX2Vycltbal1dIHw+IHVubGlzdCgpDQogICAgdF90ZXN0X3Jlc3VsdCA8LSB0LnRlc3QoeCwgeSwgcGFpcmVkID0gVFJVRSkNCiAgICBpZiAoIWlzLm5hKHRfdGVzdF9yZXN1bHQkcC52YWx1ZSkgJiB0X3Rlc3RfcmVzdWx0JHAudmFsdWUgPiAwLjA1KXsNCiAgICAgIHByaW50KHBhc3RlKCJzaW4sICIsIGRhdGEk0JzQtdGC0L7QtFtpXSwgIiAiLCBkYXRhJNCc0LXRgtC+0LRbal0sICIsIHAtdmFsID0gIiwgdF90ZXN0X3Jlc3VsdCRwLnZhbHVlKSkNCiAgICAgIH0NCiAgfQ0KfQ0KDQpmb3IgKGkgaW4gMTo2KXsNCiAgZm9yIChqIGluIChpKTo2KXsNCiAgICB4IDwtIGRhdGFfcHJldiRleHBfZXJyW1tpXV0gfD4gdW5saXN0KCkNCiAgICB5IDwtIGRhdGFfcHJldiRleHBfZXJyW1tqXV0gfD4gdW5saXN0KCkNCiAgICB0X3Rlc3RfcmVzdWx0IDwtIHQudGVzdCh4LCB5LCBwYWlyZWQgPSBUUlVFKQ0KICAgIGlmICghaXMubmEodF90ZXN0X3Jlc3VsdCRwLnZhbHVlKSAmIHRfdGVzdF9yZXN1bHQkcC52YWx1ZSA+IDAuMDUpew0KICAgICAgcHJpbnQocGFzdGUoImV4cCwgIiwgZGF0YSTQnNC10YLQvtC0W2ldLCAiICIsIGRhdGEk0JzQtdGC0L7QtFtqXSwgIiwgcC12YWwgPSAiLCB0X3Rlc3RfcmVzdWx0JHAudmFsdWUpKX0NCiAgfQ0KfQ0KDQpmb3IgKGkgaW4gMTo2KXsNCiAgZm9yIChqIGluIChpKTo2KXsNCiAgICB4IDwtIGRhdGFfcHJldiRhbGxfZXJyW1tpXV0gfD4gdW5saXN0KCkNCiAgICB5IDwtIGRhdGFfcHJldiRhbGxfZXJyW1tqXV0gfD4gdW5saXN0KCkNCiAgICB0X3Rlc3RfcmVzdWx0IDwtIHQudGVzdCh4LCB5LCBwYWlyZWQgPSBUUlVFKQ0KICAgIGlmICghaXMubmEodF90ZXN0X3Jlc3VsdCRwLnZhbHVlKSAmIHRfdGVzdF9yZXN1bHQkcC52YWx1ZSA+IDAuMDUpew0KICAgICAgcHJpbnQocGFzdGUoImFsbF9lcnIsICIsIGRhdGEk0JzQtdGC0L7QtFtpXSwgIiAiLCBkYXRhJNCc0LXRgtC+0LRbal0sICIsIHAtdmFsID0gIiwgdF90ZXN0X3Jlc3VsdCRwLnZhbHVlKSkNCiAgICAgIH0NCiAgfQ0KfQ0KDQoNCnRhYmxlX2xhdGV4IDwtIHh0YWJsZShkYXRhLCBjYXB0aW9uID0gIkV4YW1wbGUgVGFibGUiKQ0KDQojINCo0LDQsyA0OiDQktGL0LLQvtC0INGC0LDQsdC70LjRhtGLINCyIExhVGVYINGE0LDQudC7DQpwcmludCh0YWJsZV9sYXRleCwgaW5jbHVkZS5yb3duYW1lcyA9IEZBTFNFKQ0KYGBgDQoNCiMjIyMg0J/RgNC40LzQtdGALCDQutC+0YLQvtGA0YvQuSDQvdC1INC/0L7QtNGF0L7QtNC40YIg0L3QuCDQuiDQutCw0LrQvtC80YMg0LzQtdGC0L7QtNGDDQoNCmBgYHtyfQ0KDQpgYGANCg0KYGBge3J9DQpuIDwtIDk2KjIgKyA3DQpMIDwtIDg5DQp4IDwtIDA6KG4tMSkNCnkxIDwtIHNpbigyKnBpLzEzICogeCkNCnkyIDwtIGNvcygyKnBpLzggKiB4KQ0KeTMgPC0gLXgqeC8xMDAwDQp5NCA8LSBleHAoeC81NSkNCnkgPC0geTEgKyB5MiArIHkzICsgeTQgDQpwbG90KHgsIHkpDQpYIDwtIGhhbmtlbCh5LCBMID0gTCkNCmVwcyA8LSAxLyhuKzEpDQoNCnNfc3NhIDwtIHNzYSh5LCBMKQ0KIyByX3NzYSA8LSByZWNvbnN0cnVjdChzX3NzYSwgZ3JvdXBzPWxpc3QoDQojICAgc2Vzb25hbF9zaW4gPSBjKDEsIDIpLA0KIyAgIHNlc29uYWxfY29zID0gYygzLCA0KQ0KIyApKQ0KIyBwbG90KHgsIHJfc3NhJHNlc29uYWxfc2luKQ0KIyBwbG90KHgsIHJfc3NhJHNlc29uYWxfY29zKQ0KIyBwbG90KHdjb3Ioc19zc2EsIGdyb3VwcyA9IDE6MTApLCBzY2FsZXMgPSBsaXN0KGF0ID0gYygxMCwgMjAsIDMwKSkpDQplX3NzYSA8LSBlb3NzYV9uZXcoc19zc2EsIG5lc3RlZC5ncm91cHMgPSBsaXN0KDE6MTApLCBjbHVzdF90eXBlID0gImRpc3RhbmNlIikNCmdfc2Vzb25hbF9lIDwtIGdyb3VwaW5nLmF1dG8oZV9zc2EsIGJhc2UgPSAiZWlnZW4iLA0KICAgICAgICAgICAgICAgICAgICAgICBmcmVxLmJpbnMgPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzgtZXBzLCAxLzgrZXBzKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksDQogICAgICAgICAgICAgICAgICAgICAgIHRocmVzaG9sZCA9IDAuNSkNCnJfc3NhX2UgPC0gcmVjb25zdHJ1Y3QoZV9zc2EsIGdyb3Vwcz1nX3Nlc29uYWxfZSkNCiMgcGxvdCh4LCByX3NzYV9lJHNlc29uYWxfc2luKQ0KIyBwbG90KHgsIHJfc3NhX2Ukc2Vzb25hbF9jb3MpDQoNCg0KDQpyX2ZmdCA8LSByZWNvbnN0cnVjdF9mZnQoeCwgeSkNCnJfZmZ0X2dyb3VwZWQgPC0gZ3JvdXBpbmdfY2lzc2Eocl9mZnQsDQogICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9zaW4gPSBjKDEvMTItZXBzLCAxLzEyK2VwcyksDQogICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9jb3MgPSBjKDEvOC1lcHMsIDEvOCtlcHMpDQogICAgICAgICAgICAgICAgICAgICkNCiAgICAgICAgICAgICAgICAgICAgKSR0X3Nlcmllcw0KDQojIHJfZmZ0X2dyb3VwZWQkc2Vzb25hbF9zaW4gfD4gbGVuZ3RoKCkNCg0KIyBwbG90KHgsIHJfZmZ0X2dyb3VwZWQkc2Vzb25hbF9zaW4pDQojIHBsb3QoeCwgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX2NvcykNCiMgcGxvdCh4LCByX2ZmdF9ncm91cGVkJHJlc2lkdWFscykNCg0KDQpyX2Npc3NhIDwtIGNpcmN1bGFudF9TU0EoeSwgTCkNCnJfY2lzc2FfZ3JvdXBlZCA8LSBncm91cGluZ19jaXNzYShyX2Npc3NhLA0KICAgICAgICAgICAgICAgICAgICBncm91cHMgPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzgtZXBzLCAxLzgrZXBzKQ0KICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICkkdF9zZXJpZXMNCg0KDQpyX2Npc3NhX2V4dCA8LSBjaXJjdWxhbnRfU1NBKHksIEwsIGV4dGVuZF9mbGFnID0gVFJVRSkNCnJfY2lzc2FfZ3JvdXBlZF9leHQgPC0gZ3JvdXBpbmdfY2lzc2Eocl9jaXNzYV9leHQsDQogICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9zaW4gPSBjKDEvMTItZXBzLCAxLzEyK2VwcyksDQogICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9jb3MgPSBjKDEvOC1lcHMsIDEvOCtlcHMpDQogICAgICAgICAgICAgICAgICAgICkNCiAgICAgICAgICAgICAgICAgICAgKSR0X3Nlcmllcw0KDQojIHBsb3QoeCwgcl9jaXNzYV9ncm91cGVkJHNlc29uYWxfc2luKQ0KIyBwbG90KHgsIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX2NvcykNCiMgcGxvdCh4LCByX2Npc3NhX2dyb3VwZWQkcmVzaWR1YWxzKQ0KDQpsaWJyYXJ5KHh0YWJsZSkNCg0KIyDQqNCw0LMgMjog0KHQvtC30LTQsNC90LjQtSDQv9GA0LjQvNC10YDQsCDQtNCw0L3QvdGL0YUNCmRhdGEgPC0gZGF0YS5mcmFtZSgNCiAg0JzQtdGC0L7QtCA9IGMoIlNTQSBFT1NTQSIsIkZvdXJpZXIiLCAiQ2lTU0EiLCAiQ2lTU0EgZXh0ZW5kZWQiKSwNCiAgc2luX2VyciA9IGMgKDIwLCAyMCwgMSwgMSksDQogIGNvc19lcnIgPSBjKDEsIDEsIDEsIDEpDQopDQoNCmRhdGEkY29zX2VyclsxXSA8LSBtc2UoeTEsIHJfc3NhX2Ukc2Vzb25hbF9zaW4pIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzFdIDwtIG1zZSh5Miwgcl9zc2FfZSRzZXNvbmFsX2NvcykgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCg0KZGF0YSRjb3NfZXJyWzJdIDwtIG1zZSh5MSwgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX3NpbikgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbMl0gPC0gbXNlKHkyLCByX2ZmdF9ncm91cGVkJHNlc29uYWxfY29zKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCg0KDQpkYXRhJGNvc19lcnJbM10gPC0gbXNlKHkxLCByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9zaW4pIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkc2luX2VyclszXSA8LSBtc2UoeTIsIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX2NvcykgfD4gDQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCmRhdGEkY29zX2Vycls0XSA8LSBtc2UoeTEsIHJfY2lzc2FfZ3JvdXBlZF9leHQkc2Vzb25hbF9zaW4pIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkc2luX2Vycls0XSA8LSBtc2UoeTIsIHJfY2lzc2FfZ3JvdXBlZF9leHQkc2Vzb25hbF9jb3MpIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCg0KDQoNCnRhYmxlX2xhdGV4IDwtIHh0YWJsZShkYXRhLCBjYXB0aW9uID0gIkV4YW1wbGUgVGFibGUiKQ0KDQojINCo0LDQsyA0OiDQktGL0LLQvtC0INGC0LDQsdC70LjRhtGLINCyIExhVGVYINGE0LDQudC7DQpwcmludCh0YWJsZV9sYXRleCwgaW5jbHVkZS5yb3duYW1lcyA9IEZBTFNFKQ0KYGBgDQoNCiMg0KLQvtGH0L3QsNGPINGA0LDQt9C00LXQu9C40LzQvtGB0YLRjC4g0J/RgNC40LzQtdGA0YsNCg0KYGBge3J9DQpsaWJyYXJ5KFJzc2EpDQpgYGANCg0KYGBge3J9DQpkb19vbmVfZXhwZXJpbWVudCA8LSBmdW5jdGlvbihtZXRob2RzX2xpc3QsIG1ldGhvZHNfbmFtZXMpew0KICANCn0NCmBgYA0KDQpgYGB7cn0NCm4gPC0gOTYqMg0KTCA8LSA5Ng0KeCA8LSAwOihuLTEpDQp5MSA8LSBzaW4oMipwaS8xMiAqIHgpDQp5MiA8LSBjb3MoMipwaS8zICogeCkvMg0KeSA8LSB5MSArIHkyDQpYIDwtIGhhbmtlbCh5LCBMID0gTCkNCmVwcyA8LSAxLyhuKzEpDQoNCnNfc3NhIDwtIHNzYSh5WzE6KG4tMSldLCBMKQ0Kcl9zc2EgPC0gcmVjb25zdHJ1Y3Qoc19zc2EsIGdyb3VwcyA9IGxpc3QoDQogIEYxID0gYygxLCAyKSwNCiAgRjIgPSBjKDMsIDQpDQopKQ0KIyByX3NzYSA8LSByZWNvbnN0cnVjdChzX3NzYSwgZ3JvdXBzPWxpc3QoDQojICAgc2Vzb25hbF9zaW4gPSBjKDEsIDIpLA0KIyAgIHNlc29uYWxfY29zID0gYygzLCA0KQ0KIyApKQ0KIyBwbG90KHgsIHJfc3NhJEYxLCB0eXBlPSJsIikNCiMgcGxvdCh4LCByX3NzYSRGMiwgdHlwZT0gImwiKQ0KIyBwbG90KHdjb3Ioc19zc2EsIGdyb3VwcyA9IDE6MTApLCBzY2FsZXMgPSBsaXN0KGF0ID0gYygxMCwgMjAsIDMwKSkpDQplX3NzYSA8LSBlb3NzYV9uZXcoc19zc2EsIG5lc3RlZC5ncm91cHMgPSBsaXN0KDE6NCksIGNsdXN0X3R5cGUgPSAiZGlzdGFuY2UiKQ0KZ19zZXNvbmFsX2UgPC0gZ3JvdXBpbmcuYXV0byhlX3NzYSwgYmFzZSA9ICJlaWdlbiIsDQogICAgICAgICAgICAgICAgICAgICAgIGZyZXEuYmlucyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9zaW4gPSBjKDEvMTItZXBzLCAxLzEyK2VwcyksDQogICAgICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9jb3MgPSBjKDEvMy1lcHMsIDEvMytlcHMpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSwNCiAgICAgICAgICAgICAgICAgICAgICAgdGhyZXNob2xkID0gMC41KQ0Kcl9zc2FfZSA8LSByZWNvbnN0cnVjdChlX3NzYSwgZ3JvdXBzPWdfc2Vzb25hbF9lKQ0KIyBwbG90KHgsIHJfc3NhX2Ukc2Vzb25hbF9zaW4pDQojIHBsb3QoeCwgcl9zc2FfZSRzZXNvbmFsX2NvcykNCg0KDQoNCnJfZmZ0IDwtIHJlY29uc3RydWN0X2ZmdCh4LCB5KQ0Kcl9mZnRfZ3JvdXBlZCA8LSBncm91cGluZ19jaXNzYShyX2ZmdCwNCiAgICAgICAgICAgICAgICAgICAgZ3JvdXBzID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICApJHRfc2VyaWVzDQoNCnJfZmZ0X2V4dGVuZGVkIDwtIHJlY29uc3RydWN0X2ZmdCh4LCB5LCBUUlVFKQ0Kcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCA8LSBncm91cGluZ19jaXNzYShyX2ZmdF9leHRlbmRlZCwNCiAgICAgICAgICAgICAgICAgICAgZ3JvdXBzID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICApJHRfc2VyaWVzDQoNCiMgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX3NpbiB8PiBsZW5ndGgoKQ0KDQojIHBsb3QoeCwgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX3NpbikNCiMgcGxvdCh4LCByX2ZmdF9ncm91cGVkJHNlc29uYWxfY29zKQ0KIyBwbG90KHgsIHJfZmZ0X2dyb3VwZWQkcmVzaWR1YWxzKQ0KDQoNCnJfY2lzc2EgPC0gY2lyY3VsYW50X1NTQSh5LCBMKQ0Kcl9jaXNzYV9ncm91cGVkIDwtIGdyb3VwaW5nX2Npc3NhKHJfY2lzc2EsDQogICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9zaW4gPSBjKDEvMTItZXBzLCAxLzEyK2VwcyksDQogICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9jb3MgPSBjKDEvMy1lcHMsIDEvMytlcHMpDQogICAgICAgICAgICAgICAgICAgICkNCiAgICAgICAgICAgICAgICAgICAgKSR0X3Nlcmllcw0KDQoNCnJfY2lzc2FfZXh0IDwtIGNpcmN1bGFudF9TU0EoeSwgTCwgZXh0ZW5kX2ZsYWcgPSBUUlVFKQ0Kcl9jaXNzYV9ncm91cGVkX2V4dCA8LSBncm91cGluZ19jaXNzYShyX2Npc3NhX2V4dCwNCiAgICAgICAgICAgICAgICAgICAgZ3JvdXBzID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICApJHRfc2VyaWVzDQoNCg0KDQoNCg0KDQojIHBsb3QoeCwgcl9jaXNzYV9ncm91cGVkJHNlc29uYWxfc2luKQ0KIyBwbG90KHgsIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX2NvcykNCiMgcGxvdCh4LCByX2Npc3NhX2dyb3VwZWQkcmVzaWR1YWxzKQ0KDQpsaWJyYXJ5KHh0YWJsZSkNCg0KIyDQqNCw0LMgMjog0KHQvtC30LTQsNC90LjQtSDQv9GA0LjQvNC10YDQsCDQtNCw0L3QvdGL0YUNCmRhdGEgPC0gZGF0YS5mcmFtZSgNCiAg0JzQtdGC0L7QtCA9IGMoIlNTQSwgXG5MdywgS3cgaW4gTiIsICJTU0EgRU9TU0EsIFxuTHcsIEt3IGluIE4iLCJGb3VyaWVyLCBOdyBpbiBOIiwgIkNpU1NBLCBMdyBpbiBOIiwgIkNpU1NBIGV4dGVuZGVkLCBMdyBpbiBOIiwgIkZvdXJpZXIgZXh0ZW5kZWQsIE53IGluIE4iLA0KICAgICAgICAgICAgIlNTQSwgXG5MdyBpbiBOLCBLdyBub3QgaW4gTiIsICJTU0EgRU9TU0EsIFxuTHcgaW4gTiwgS3cgbm90IGluIE4iLCJGb3VyaWVyLCBOdyBub3QgaW4gTiIsICJDaVNTQSwgTHcgbm90IGluIE4iLCAiQ2lTU0EgZXh0ZW5kZWQsIEx3IG5vdCBpbiBOIiwgIkZvdXJpZXIgZXh0ZW5kZWQsIE53IG5vdCBpbiBOIiksDQogIHNpbl9lcnIgPSBjICgxLCAyMCwgMjAsIDEsIDEsIDEsIDEsIDIwLCAyMCwgMSwgMSwgMSksDQogIGNvc19lcnIgPSBjKDEsIDEsIDEsIDEsIDEsIDEsIDEsIDIwLCAyMCwgMSwgMSwgMSksDQogIGFsbF9lcnIgPSBjKDEsIDEsIDEsIDEsIDEsIDEsIDEsIDIwLCAyMCwgMSwgMSwgMSkNCikNCg0KZGF0YSRzaW5fZXJyWzFdIDwtIG1zZSh5MVsxOihuLTEpXSwgcl9zc2EkRjEpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKSANCmRhdGEkY29zX2VyclsxXSA8LSBtc2UoeTJbMToobi0xKV0sIHJfc3NhJEYyKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2VyclsxXSA8LSBtc2UoeTFbMToobi0xKV0gKyB5MlsxOihuLTEpXSwgcl9zc2EkRjEgKyByX3NzYSRGMikgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCmRhdGEkY29zX2VyclsyXSA8LSBtc2UoeTFbMToobi0xKV0sIHJfc3NhX2Ukc2Vzb25hbF9zaW4pIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzJdIDwtIG1zZSh5MlsxOihuLTEpXSwgcl9zc2FfZSRzZXNvbmFsX2NvcykgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbMl0gPC0gbXNlKHkxWzE6KG4tMSldICsgeTJbMToobi0xKV0sDQogICAgICAgICAgICAgICAgICAgICAgIHJfc3NhX2Ukc2Vzb25hbF9zaW4gKyByX3NzYV9lJHNlc29uYWxfY29zKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCg0KDQpkYXRhJGNvc19lcnJbM10gPC0gbXNlKHkxLCByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkc2luX2VyclszXSA8LSBtc2UoeTIsIHJfZmZ0X2dyb3VwZWQkc2Vzb25hbF9jb3MpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzNdIDwtIG1zZSh5MSArIHkyLA0KICAgICAgICAgICAgICAgICAgICAgICByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luICsgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX2Nvcw0KICAgICAgICAgICAgICAgICAgICAgICApIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCmRhdGEkY29zX2Vycls0XSA8LSBtc2UoeTEsIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX3NpbikgfD4gDQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzRdIDwtIG1zZSh5Miwgcl9jaXNzYV9ncm91cGVkJHNlc29uYWxfY29zKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbNF0gPC0gbXNlKHkxICsgeTIsDQogICAgICAgICAgICAgICAgICAgICAgIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX3NpbiArIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX2Nvcw0KICAgICAgICAgICAgICAgICAgICAgICApIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCmRhdGEkY29zX2Vycls1XSA8LSBtc2UoeTEsIHJfY2lzc2FfZ3JvdXBlZF9leHQkc2Vzb25hbF9zaW4pIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkc2luX2Vycls1XSA8LSBtc2UoeTIsIHJfY2lzc2FfZ3JvdXBlZF9leHQkc2Vzb25hbF9jb3MpIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2Vycls1XSA8LSBtc2UoeTEgKyB5MiwNCiAgICAgICAgICAgICAgICAgICAgICAgcl9jaXNzYV9ncm91cGVkX2V4dCRzZXNvbmFsX3NpbiArIHJfY2lzc2FfZ3JvdXBlZF9leHQkc2Vzb25hbF9jb3MNCiAgICAgICAgICAgICAgICAgICAgICAgKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCg0KDQpkYXRhJGNvc19lcnJbNl0gPC0gbXNlKHkxLCByX2ZmdF9ncm91cGVkX2V4dGVuZGVkJHNlc29uYWxfc2luKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkc2luX2Vycls2XSA8LSBtc2UoeTIsIHJfZmZ0X2dyb3VwZWRfZXh0ZW5kZWQkc2Vzb25hbF9jb3MpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzZdIDwtIG1zZSh5MSArIHkyLA0KICAgICAgICAgICAgICAgICAgICAgICByX2ZmdF9ncm91cGVkX2V4dGVuZGVkJHNlc29uYWxfc2luICsgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX2Nvcw0KICAgICAgICAgICAgICAgICAgICAgICApIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCg0KIy0tLS0tLS0tLS0tLS0tLS0tLQ0KDQplcHMgPC0gZXBzKjINCg0Kc19zc2EgPC0gc3NhKHksIEwpDQpyX3NzYSA8LSByZWNvbnN0cnVjdChzX3NzYSwgZ3JvdXBzID0gbGlzdCgNCiAgRjEgPSBjKDEsIDIpLA0KICBGMiA9IGMoMywgNCkNCikpDQojIHJfc3NhIDwtIHJlY29uc3RydWN0KHNfc3NhLCBncm91cHM9bGlzdCgNCiMgICBzZXNvbmFsX3NpbiA9IGMoMSwgMiksDQojICAgc2Vzb25hbF9jb3MgPSBjKDMsIDQpDQojICkpDQojIHBsb3QoeCwgcl9zc2EkRjEsIHR5cGU9ImwiKQ0KIyBwbG90KHgsIHJfc3NhJEYyLCB0eXBlPSAibCIpDQojIHBsb3Qod2NvcihzX3NzYSwgZ3JvdXBzID0gMToxMCksIHNjYWxlcyA9IGxpc3QoYXQgPSBjKDEwLCAyMCwgMzApKSkNCmVfc3NhIDwtIGVvc3NhX25ldyhzX3NzYSwgbmVzdGVkLmdyb3VwcyA9IGxpc3QoMTo0KSwgY2x1c3RfdHlwZSA9ICJkaXN0YW5jZSIpDQpnX3Nlc29uYWxfZSA8LSBncm91cGluZy5hdXRvKGVfc3NhLCBiYXNlID0gImVpZ2VuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgZnJlcS5iaW5zID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLA0KICAgICAgICAgICAgICAgICAgICAgICB0aHJlc2hvbGQgPSAwLjUpDQpyX3NzYV9lIDwtIHJlY29uc3RydWN0KGVfc3NhLCBncm91cHM9Z19zZXNvbmFsX2UpDQojIHBsb3QoeCwgcl9zc2FfZSRzZXNvbmFsX3NpbikNCiMgcGxvdCh4LCByX3NzYV9lJHNlc29uYWxfY29zKQ0KDQoNCg0Kcl9mZnQgPC0gcmVjb25zdHJ1Y3RfZmZ0KHhbMToobi0xKV0sIHlbMToobi0xKV0pDQpyX2ZmdF9ncm91cGVkIDwtIGdyb3VwaW5nX2Npc3NhKHJfZmZ0LA0KICAgICAgICAgICAgICAgICAgICBncm91cHMgPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICkkdF9zZXJpZXMNCg0Kcl9mZnRfZXh0ZW5kZWQgPC0gcmVjb25zdHJ1Y3RfZmZ0KHhbMToobi0xKV0sIHlbMToobi0xKV0sIFRSVUUpDQpyX2ZmdF9ncm91cGVkX2V4dGVuZGVkIDwtIGdyb3VwaW5nX2Npc3NhKHJfZmZ0X2V4dGVuZGVkLA0KICAgICAgICAgICAgICAgICAgICBncm91cHMgPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICkkdF9zZXJpZXMNCg0KIyByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luIHw+IGxlbmd0aCgpDQoNCiMgcGxvdCh4LCByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luKQ0KIyBwbG90KHgsIHJfZmZ0X2dyb3VwZWQkc2Vzb25hbF9jb3MpDQojIHBsb3QoeCwgcl9mZnRfZ3JvdXBlZCRyZXNpZHVhbHMpDQoNCg0Kcl9jaXNzYSA8LSBjaXJjdWxhbnRfU1NBKHksIEwrMSkNCnJfY2lzc2FfZ3JvdXBlZCA8LSBncm91cGluZ19jaXNzYShyX2Npc3NhLA0KICAgICAgICAgICAgICAgICAgICBncm91cHMgPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICkkdF9zZXJpZXMNCg0KDQpyX2Npc3NhX2V4dCA8LSBjaXJjdWxhbnRfU1NBKHksIEwrMSwgZXh0ZW5kX2ZsYWcgPSBUUlVFKQ0Kcl9jaXNzYV9ncm91cGVkX2V4dCA8LSBncm91cGluZ19jaXNzYShyX2Npc3NhX2V4dCwNCiAgICAgICAgICAgICAgICAgICAgZ3JvdXBzID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICApJHRfc2VyaWVzDQoNCg0KDQoNCg0KZGF0YSRzaW5fZXJyWzddIDwtIG1zZSh5MSwgcl9zc2EkRjEpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKSANCmRhdGEkY29zX2Vycls3XSA8LSBtc2UoeTIsIHJfc3NhJEYyKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2Vycls3XSA8LSBtc2UoeTEgKyB5Miwgcl9zc2EkRjEgKyByX3NzYSRGMikgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCmRhdGEkY29zX2Vycls4XSA8LSBtc2UoeTEsIHJfc3NhX2Ukc2Vzb25hbF9zaW4pIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzhdIDwtIG1zZSh5Miwgcl9zc2FfZSRzZXNvbmFsX2NvcykgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbOF0gPC0gbXNlKHkxICsgeTIsDQogICAgICAgICAgICAgICAgICAgICAgIHJfc3NhX2Ukc2Vzb25hbF9zaW4gKyByX3NzYV9lJHNlc29uYWxfY29zKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCg0KDQpkYXRhJGNvc19lcnJbOV0gPC0gbXNlKHkxWzE6KG4tMSldLCByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkc2luX2Vycls5XSA8LSBtc2UoeTJbMToobi0xKV0sIHJfZmZ0X2dyb3VwZWQkc2Vzb25hbF9jb3MpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzldIDwtIG1zZSh5MVsxOihuLTEpXSArIHkyWzE6KG4tMSldLA0KICAgICAgICAgICAgICAgICAgICAgICByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luICsgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX2Nvcw0KICAgICAgICAgICAgICAgICAgICAgICApIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCmRhdGEkY29zX2VyclsxMF0gPC0gbXNlKHkxLCByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9zaW4pIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkc2luX2VyclsxMF0gPC0gbXNlKHkyLCByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9jb3MpIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2VyclsxMF0gPC0gbXNlKHkxICsgeTIsDQogICAgICAgICAgICAgICAgICAgICAgIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX3NpbiArIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX2Nvcw0KICAgICAgICAgICAgICAgICAgICAgICApIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCmRhdGEkY29zX2VyclsxMV0gPC0gbXNlKHkxLCByX2Npc3NhX2dyb3VwZWRfZXh0JHNlc29uYWxfc2luKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbMTFdIDwtIG1zZSh5Miwgcl9jaXNzYV9ncm91cGVkX2V4dCRzZXNvbmFsX2NvcykgfD4gDQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzExXSA8LSBtc2UoeTEgKyB5MiwNCiAgICAgICAgICAgICAgICAgICAgICAgcl9jaXNzYV9ncm91cGVkX2V4dCRzZXNvbmFsX3NpbiArIHJfY2lzc2FfZ3JvdXBlZF9leHQkc2Vzb25hbF9jb3MNCiAgICAgICAgICAgICAgICAgICAgICAgKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCg0KDQpkYXRhJGNvc19lcnJbMTJdIDwtIG1zZSh5MVsxOihuLTEpXSwgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX3NpbikgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbMTJdIDwtIG1zZSh5MlsxOihuLTEpXSwgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX2NvcykgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbMTJdIDwtIG1zZSh5MVsxOihuLTEpXSArIHkyWzE6KG4tMSldLA0KICAgICAgICAgICAgICAgICAgICAgICByX2ZmdF9ncm91cGVkX2V4dGVuZGVkJHNlc29uYWxfc2luICsgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX2Nvcw0KICAgICAgICAgICAgICAgICAgICAgICApIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCg0KDQoNCg0KdGFibGVfbGF0ZXggPC0geHRhYmxlKGRhdGEsIGNhcHRpb24gPSAiRXhhbXBsZSBUYWJsZSIpDQoNCiMg0KjQsNCzIDQ6INCS0YvQstC+0LQg0YLQsNCx0LvQuNGG0Ysg0LIgTGFUZVgg0YTQsNC50LsNCnByaW50KHRhYmxlX2xhdGV4LCBpbmNsdWRlLnJvd25hbWVzID0gRkFMU0UpDQoNCmBgYA0KDQojIyMg0KLQtSDQttC1INC/0YDQuNC80LXRgNGLINGBINGI0YPQvNC+0LwNCg0KYGBge3J9DQpkYXRhIDwtIGxpc3QoDQogINCc0LXRgtC+0LQgPSBjKCJTU0EiLCJTU0EgRU9TU0EiLCJGb3VyaWVyIiwgIkNpU1NBIiwgIkNpU1NBIGV4dGVuZGVkIiwgIkZvdXJpZXIgZXh0ZW5kZWQiKSwNCiAgc2luX2VyciA9IGxpc3QobGlzdCgpLCBsaXN0KCksIGxpc3QoKSwgbGlzdCgpLCBsaXN0KCksIGxpc3QoKSksDQogIGNvc19lcnIgPSBsaXN0KGxpc3QoKSwgbGlzdCgpLCBsaXN0KCksIGxpc3QoKSwgbGlzdCgpLCBsaXN0KCkpLA0KICBhbGxfZXJyID0gbGlzdChsaXN0KCksIGxpc3QoKSwgbGlzdCgpLCBsaXN0KCksIGxpc3QoKSwgbGlzdCgpKQ0KKQ0KDQpmb3IgKGkgaW4gMToxMDApew0KICBzZXQuc2VlZChpKQ0KICANCiAgbiA8LSA5NioyDQogIEwgPC0gOTYNCiAgeCA8LSAwOihuLTEpDQogIHkxIDwtIHNpbigyKnBpLzEyICogeCkNCiAgeTIgPC0gY29zKDIqcGkvMyAqIHgpLzINCiAgeSA8LSB5MSArIHkyICsgcm5vcm0obiwgMCwgMC4xKQ0KICBYIDwtIGhhbmtlbCh5LCBMID0gTCkNCiAgZXBzIDwtIDEvKG4rMSkNCiAgDQogIHNfc3NhIDwtIHNzYSh5WzE6KG4tMSldLCBMKQ0KICByX3NzYSA8LSByZWNvbnN0cnVjdChzX3NzYSwgZ3JvdXBzID0gbGlzdCgNCiAgICBGMSA9IGMoMSwgMiksDQogICAgRjIgPSBjKDMsIDQpDQogICkpDQogICMgcl9zc2EgPC0gcmVjb25zdHJ1Y3Qoc19zc2EsIGdyb3Vwcz1saXN0KA0KICAjICAgc2Vzb25hbF9zaW4gPSBjKDEsIDIpLA0KICAjICAgc2Vzb25hbF9jb3MgPSBjKDMsIDQpDQogICMgKSkNCiAgIyBwbG90KHhbMToobi0xKV0sIHJfc3NhJEYxLCB0eXBlID0gImwiKQ0KICAjIHBsb3QoeFsxOihuLTEpXSwgcl9zc2EkRjIsIHR5cGUgPSAibCIpDQogICMgcGxvdCh3Y29yKHNfc3NhLCBncm91cHMgPSAxOjEwKSwgc2NhbGVzID0gbGlzdChhdCA9IGMoMTAsIDIwLCAzMCkpKQ0KICBlX3NzYSA8LSBlb3NzYV9uZXcoc19zc2EsIG5lc3RlZC5ncm91cHMgPSBsaXN0KDE6NCksIGNsdXN0X3R5cGUgPSAiZGlzdGFuY2UiKQ0KICBnX3Nlc29uYWxfZSA8LSBncm91cGluZy5hdXRvKGVfc3NhLCBiYXNlID0gImVpZ2VuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICBmcmVxLmJpbnMgPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9zaW4gPSBjKDEvMTItZXBzLCAxLzEyK2VwcyksDQogICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksDQogICAgICAgICAgICAgICAgICAgICAgICAgdGhyZXNob2xkID0gMC41KQ0KICByX3NzYV9lIDwtIHJlY29uc3RydWN0KGVfc3NhLCBncm91cHM9Z19zZXNvbmFsX2UpDQogICMgcGxvdCh4LCByX3NzYV9lJHNlc29uYWxfc2luKQ0KICAjIHBsb3QoeCwgcl9zc2FfZSRzZXNvbmFsX2NvcykNCiAgDQogIA0KICANCiAgcl9mZnQgPC0gcmVjb25zdHJ1Y3RfZmZ0KHgsIHkpDQogIHJfZmZ0X2dyb3VwZWQgPC0gZ3JvdXBpbmdfY2lzc2Eocl9mZnQsDQogICAgICAgICAgICAgICAgICAgICAgZ3JvdXBzID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9jb3MgPSBjKDEvMy1lcHMsIDEvMytlcHMpDQogICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICAgICkkdF9zZXJpZXMNCiAgDQogIHJfZmZ0X2V4dGVuZGVkIDwtIHJlY29uc3RydWN0X2ZmdCh4LCB5LCBUUlVFKQ0KICByX2ZmdF9ncm91cGVkX2V4dGVuZGVkIDwtIGdyb3VwaW5nX2Npc3NhKHJfZmZ0X2V4dGVuZGVkLA0KICAgICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICAgICkNCiAgICAgICAgICAgICAgICAgICAgICApJHRfc2VyaWVzDQogIA0KICAjIHJfZmZ0X2dyb3VwZWQkc2Vzb25hbF9zaW4gfD4gbGVuZ3RoKCkNCiAgDQogICMgcGxvdCh4LCByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luKQ0KICAjIHBsb3QoeCwgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX2NvcykNCiAgIyBwbG90KHgsIHJfZmZ0X2dyb3VwZWQkcmVzaWR1YWxzKQ0KICANCiAgDQogIHJfY2lzc2EgPC0gY2lyY3VsYW50X1NTQSh5LCBMKQ0KICByX2Npc3NhX2dyb3VwZWQgPC0gZ3JvdXBpbmdfY2lzc2Eocl9jaXNzYSwNCiAgICAgICAgICAgICAgICAgICAgICBncm91cHMgPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9zaW4gPSBjKDEvMTItZXBzLCAxLzEyK2VwcyksDQogICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgKSR0X3Nlcmllcw0KICANCiAgDQogIHJfY2lzc2FfZXh0IDwtIGNpcmN1bGFudF9TU0EoeSwgTCwgZXh0ZW5kX2ZsYWcgPSBUUlVFKQ0KICByX2Npc3NhX2dyb3VwZWRfZXh0IDwtIGdyb3VwaW5nX2Npc3NhKHJfY2lzc2FfZXh0LA0KICAgICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICAgICkNCiAgICAgICAgICAgICAgICAgICAgICApJHRfc2VyaWVzDQogIGRhdGEkY29zX2VycltbMV1dW1tpXV0gPC0gDQogICAgbWluKG1zZSh5MVsxOihuLTEpXSwgcl9zc2EkRjEpLCBtc2UoeTFbMToobi0xKV0sIHJfc3NhJEYyKSkNCiAgZGF0YSRzaW5fZXJyW1sxXV1bW2ldXSA8LQ0KICAgIG1pbihtc2UoeTJbMToobi0xKV0sIHJfc3NhJEYxKSwgbXNlKHkyWzE6KG4tMSldLCByX3NzYSRGMikpDQogIGRhdGEkYWxsX2VycltbMV1dW1tpXV0gPC0NCiAgICBtaW4obXNlKHkxWzE6KG4tMSldK3kyWzE6KG4tMSldLCByX3NzYSRGMSsgcl9zc2EkRjIpKQ0KICANCiAgZGF0YSRjb3NfZXJyW1syXV1bW2ldXSA8LSBtc2UoeTFbMToobi0xKV0sIHJfc3NhX2Ukc2Vzb25hbF9zaW4pDQogIGRhdGEkc2luX2VycltbMl1dW1tpXV0gPC0gbXNlKHkyWzE6KG4tMSldLCByX3NzYV9lJHNlc29uYWxfY29zKQ0KICBkYXRhJGFsbF9lcnJbWzJdXVtbaV1dIDwtIG1zZSh5MVsxOihuLTEpXSsgeTJbMToobi0xKV0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJfc3NhX2Ukc2Vzb25hbF9zaW4gKyByX3NzYV9lJHNlc29uYWxfY29zKQ0KICANCiAgDQogIGRhdGEkY29zX2VycltbM11dW1tpXV0gPC0gbXNlKHkxLCByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luKQ0KICBkYXRhJHNpbl9lcnJbWzNdXVtbaV1dIDwtIG1zZSh5Miwgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX2NvcykNCiAgZGF0YSRhbGxfZXJyW1szXV1bW2ldXSA8LSBtc2UoeTEgKyB5MiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX2NvcyArICByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luKQ0KICANCiAgDQogIGRhdGEkY29zX2VycltbNF1dW1tpXV0gPC0gbXNlKHkxLCByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9zaW4pDQogIGRhdGEkc2luX2VycltbNF1dW1tpXV0gPC0gbXNlKHkyLCByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9jb3MpDQogIGRhdGEkYWxsX2VycltbNF1dW1tpXV0gPC0gbXNlKHkxICsgeTIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX3NpbiArICByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9jb3MNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICANCiAgZGF0YSRjb3NfZXJyW1s1XV1bW2ldXSA8LSBtc2UoeTEsIHJfY2lzc2FfZ3JvdXBlZF9leHQkc2Vzb25hbF9zaW4pDQogIGRhdGEkc2luX2VycltbNV1dW1tpXV0gPC0gbXNlKHkyLCByX2Npc3NhX2dyb3VwZWRfZXh0JHNlc29uYWxfY29zKQ0KICBkYXRhJGFsbF9lcnJbWzVdXVtbaV1dIDwtIG1zZSh5MSArIHkyLA0KICAgICAgICAgICAgICAgICAgICAgICAgICByX2Npc3NhX2dyb3VwZWRfZXh0JHNlc29uYWxfc2luICsgcl9jaXNzYV9ncm91cGVkX2V4dCRzZXNvbmFsX2Nvcw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogIA0KICBkYXRhJGNvc19lcnJbWzZdXVtbaV1dIDwtIG1zZSh5MSwgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX3NpbikNCiAgZGF0YSRzaW5fZXJyW1s2XV1bW2ldXSA8LSBtc2UoeTIsIHJfZmZ0X2dyb3VwZWRfZXh0ZW5kZWQkc2Vzb25hbF9jb3MpDQogIGRhdGEkYWxsX2VycltbNl1dW1tpXV0gPC0gbXNlKHkxICsgeTIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJfZmZ0X2dyb3VwZWRfZXh0ZW5kZWQkc2Vzb25hbF9zaW4gKyByX2ZmdF9ncm91cGVkX2V4dGVuZGVkJHNlc29uYWxfY29zDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkNCn0NCmxpYnJhcnkoeHRhYmxlKQ0KDQojINCo0LDQsyAyOiDQodC+0LfQtNCw0L3QuNC1INC/0YDQuNC80LXRgNCwINC00LDQvdC90YvRhQ0KZGF0YV9wcmV2IDwtIGRhdGENCg0KZGF0YSA8LSBkYXRhLmZyYW1lKA0KICDQnNC10YLQvtC0ID0gYygiU1NBIiwgIlNTQSBFT1NTQSIsIkZvdXJpZXIiLCAiQ2lTU0EiLCAiQ2lTU0EgZXh0ZW5kZWQiLCAiRm91cmllciBleHRlbmRlZCIpLA0KICBzaW5fZXJyID0gYygwLCAwLCAwLCAwLCAwLCAwKSwNCiAgY29zX2VyciA9IGMoMCwgMCwgMCwgMCwgMCwgMCksDQogIGFsbF9lcnIgPSBjKDAsIDAsIDAsIDAsIDAsIDApDQopDQoNCmRhdGEkY29zX2VyclsxXSA8LSBtZWFuKGRhdGFfcHJldiRjb3NfZXJyW1sxXV0gfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzFdIDwtIG1lYW4oZGF0YV9wcmV2JHNpbl9lcnJbWzFdXXw+IHVubGlzdCgpKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2VyclsxXSA8LSBtZWFuKGRhdGFfcHJldiRhbGxfZXJyW1sxXV18PiB1bmxpc3QoKSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCmRhdGEkY29zX2VyclsyXSA8LSBtZWFuKGRhdGFfcHJldiRjb3NfZXJyW1syXV0gfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzJdIDwtIG1lYW4oZGF0YV9wcmV2JHNpbl9lcnJbWzJdXXw+IHVubGlzdCgpKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2VyclsyXSA8LSBtZWFuKGRhdGFfcHJldiRhbGxfZXJyW1syXV18PiB1bmxpc3QoKSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCg0KZGF0YSRjb3NfZXJyWzNdIDwtIG1lYW4oZGF0YV9wcmV2JGNvc19lcnJbWzNdXXw+IHVubGlzdCgpKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkc2luX2VyclszXSA8LSBtZWFuKGRhdGFfcHJldiRzaW5fZXJyW1szXV18PiB1bmxpc3QoKSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbM10gPC0gbWVhbihkYXRhX3ByZXYkYWxsX2VycltbM11dfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCmRhdGEkY29zX2Vycls0XSA8LSBtZWFuKGRhdGFfcHJldiRjb3NfZXJyW1s0XV18PiB1bmxpc3QoKSkgfD4gDQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzRdIDwtIG1lYW4oZGF0YV9wcmV2JHNpbl9lcnJbWzRdXXw+IHVubGlzdCgpKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbNF0gPC0gbWVhbihkYXRhX3ByZXYkYWxsX2VycltbNF1dfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCmRhdGEkY29zX2Vycls1XSA8LSBtZWFuKGRhdGFfcHJldiRjb3NfZXJyW1s1XV18PiB1bmxpc3QoKSkgfD4gDQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzVdIDwtIG1lYW4oZGF0YV9wcmV2JHNpbl9lcnJbWzVdXXw+IHVubGlzdCgpKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbNV0gPC0gbWVhbihkYXRhX3ByZXYkYWxsX2VycltbNV1dfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQpkYXRhJGNvc19lcnJbNl0gPC0gbWVhbihkYXRhX3ByZXYkY29zX2VycltbNl1dfD4gdW5saXN0KCkpIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkc2luX2Vycls2XSA8LSBtZWFuKGRhdGFfcHJldiRzaW5fZXJyW1s2XV18PiB1bmxpc3QoKSkgfD4gDQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzZdIDwtIG1lYW4oZGF0YV9wcmV2JGFsbF9lcnJbWzZdXXw+IHVubGlzdCgpKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCg0KYGBgDQoNCiMg0JDRgdGB0LjQvNC/0YLQvtGC0LjRh9C10YHQutCw0Y8g0YDQsNC30LTQtdC70LjQvNC+0YHRgtGMICjQsdC10YHQv9C+0LvQtdC30L3QvikNCg0KYGBge3J9DQoNCm4gPC0gOTYqMg0KeCA8LSAwOihuLTEpDQpMIDwtIDk2DQp5MSA8LSBzaW4oMipwaS8xMiAqIHgpDQp5MiA8LSBjb3MoMipwaS8zICogeCkvMg0KeTMgPC0gZXhwKHgvMTApICsgMSANCnkgPC0geTEgKyB5MiArIHkzDQplcHMgPC0gMS8obisxKQ0KDQpzX3NzYSA8LSBzc2EoeVsxOihuLTEpXSwgTCkNCnJfc3NhIDwtIHJlY29uc3RydWN0KHNfc3NhLCBncm91cHM9bGlzdCgNCiAgZSA9IGMoMSksDQogIHNlc29uYWxfc2luID0gYygyLCAzKSwNCiAgc2Vzb25hbF9jb3MgPSBjKDQsIDUpDQopKQ0KIyBwbG90KHhbMToobi0xKV0sIHJfc3NhJGUsIHR5cGUgPSAibCIpDQojIHBsb3QoeFsxOihuLTEpXSwgcl9zc2Ekc2Vzb25hbF9zaW4sIHR5cGUgPSAibCIpDQojIHBsb3QoeFsxOihuLTEpXSwgcl9zc2Ekc2Vzb25hbF9jb3MsIHR5cGUgPSAibCIpDQojIHBsb3Qod2NvcihzX3NzYSwgZ3JvdXBzID0gMToxMCksIHNjYWxlcyA9IGxpc3QoYXQgPSBjKDEwLCAyMCwgMzApKSkNCmVfc3NhIDwtIGVvc3NhX25ldyhzX3NzYSwgbmVzdGVkLmdyb3VwcyA9IGxpc3QoMTo3KSwgY2x1c3RfdHlwZSA9ICJkaXN0YW5jZSIpDQpnX3Nlc29uYWxfZSA8LSBncm91cGluZy5hdXRvKGVfc3NhLCBiYXNlID0gImVpZ2VuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgZnJlcS5iaW5zID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICAgICBlID0gYygwLCAxLzEyLWVwcy1lcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksDQogICAgICAgICAgICAgICAgICAgICAgIHRocmVzaG9sZCA9IDAuNSkNCnJfc3NhX2UgPC0gcmVjb25zdHJ1Y3QoZV9zc2EsIGdyb3Vwcz1nX3Nlc29uYWxfZSkNCiMgcGxvdCh4LCByX3NzYV9lJHNlc29uYWxfc2luKQ0KIyBwbG90KHgsIHJfc3NhX2Ukc2Vzb25hbF9jb3MpDQoNCg0KDQpyX2ZmdCA8LSByZWNvbnN0cnVjdF9mZnQoeCwgeSkNCnJfZmZ0X2dyb3VwZWQgPC0gZ3JvdXBpbmdfY2lzc2Eocl9mZnQsDQogICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgZSA9IGMoMCwgMS8xMi1lcHMtZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICApJHRfc2VyaWVzDQoNCnJfZmZ0X2V4dGVuZGVkIDwtIHJlY29uc3RydWN0X2ZmdCh4LCB5LCBUUlVFKQ0Kcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCA8LSBncm91cGluZ19jaXNzYShyX2ZmdF9leHRlbmRlZCwNCiAgICAgICAgICAgICAgICAgICAgZ3JvdXBzID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICBlID0gYygwLCAxLzEyLWVwcy1lcHMpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICkkdF9zZXJpZXMNCg0KIyByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luIHw+IGxlbmd0aCgpDQoNCiMgcGxvdCh4LCByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luKQ0KIyBwbG90KHgsIHJfZmZ0X2dyb3VwZWQkc2Vzb25hbF9jb3MpDQojIHBsb3QoeCwgcl9mZnRfZ3JvdXBlZCRyZXNpZHVhbHMpDQoNCg0Kcl9jaXNzYSA8LSBjaXJjdWxhbnRfU1NBKHksIEwpDQpyX2Npc3NhX2dyb3VwZWQgPC0gZ3JvdXBpbmdfY2lzc2Eocl9jaXNzYSwNCiAgICAgICAgICAgICAgICAgICAgZ3JvdXBzID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICBlID0gYygwLCAxLzEyLWVwcy1lcHMpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICkkdF9zZXJpZXMNCg0KDQpyX2Npc3NhX2V4dCA8LSBjaXJjdWxhbnRfU1NBKHksIEwsIGV4dGVuZF9mbGFnID0gVFJVRSkNCnJfY2lzc2FfZ3JvdXBlZF9leHQgPC0gZ3JvdXBpbmdfY2lzc2Eocl9jaXNzYV9leHQsDQogICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgZSA9IGMoMCwgMS8xMi1lcHMtZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICApJHRfc2VyaWVzDQoNCiMgcGxvdCh4LCByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9zaW4pDQojIHBsb3QoeCwgcl9jaXNzYV9ncm91cGVkJHNlc29uYWxfY29zKQ0KIyBwbG90KHgsIHJfY2lzc2FfZ3JvdXBlZCRyZXNpZHVhbHMpDQoNCmxpYnJhcnkoeHRhYmxlKQ0KDQojINCo0LDQsyAyOiDQodC+0LfQtNCw0L3QuNC1INC/0YDQuNC80LXRgNCwINC00LDQvdC90YvRhQ0KZGF0YSA8LSBkYXRhLmZyYW1lKA0KICDQnNC10YLQvtC0ID0gYygiU1NBIiwgIlNTQSBFT1NTQSIsIkZvdXJpZXIiLCAiQ2lTU0EiLCAiQ2lTU0EgZXh0ZW5kZWQiLCAiRm91cmllciBleHRlbmRlZCIpLA0KICBlX2VyciA9IGMoMSwgMSwgMSwgMSwgMSwgMSksDQogIHNpbl9lcnIgPSBjICgxLCAyMCwgMjAsIDEsIDEsIDEpLA0KICBjb3NfZXJyID0gYygxLCAxLCAxLCAxLCAxLCAxKSwNCiAgYWxsX2VyciA9IGMoMSwgMSwgMSwgMSwgMSwgMSkNCikNCg0KZGF0YSRjb3NfZXJyWzFdIDwtIG1zZSh5MVsxOihuLTEpXSwgcl9zc2Ekc2Vzb25hbF9zaW4pIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzFdIDwtIG1zZSh5MlsxOihuLTEpXSwgcl9zc2Ekc2Vzb25hbF9jb3MpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRlX2VyclsxXSA8LSBtc2UoeTNbMToobi0xKV0sIHJfc3NhJGUpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzFdIDwtIG1zZSh5MVsxOihuLTEpXSsgeTJbMToobi0xKV0gKyB5M1sxOihuLTEpXSwNCiAgICAgICAgICAgICAgICAgICAgIHJfc3NhJHNlc29uYWxfc2luICsgcl9zc2Ekc2Vzb25hbF9jb3MgKyByX3NzYSRlKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCg0KZGF0YSRjb3NfZXJyWzJdIDwtIG1zZSh5MVsxOihuLTEpXSwgcl9zc2FfZSRzZXNvbmFsX3NpbikgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbMl0gPC0gbXNlKHkyWzE6KG4tMSldLCByX3NzYV9lJHNlc29uYWxfY29zKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkZV9lcnJbMl0gPC0gbXNlKHkzWzE6KG4tMSldLCByX3NzYV9lJGUpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzJdIDwtIG1zZSh5MVsxOihuLTEpXSsgeTJbMToobi0xKV0gKyB5M1sxOihuLTEpXSwNCiAgICAgICAgICAgICAgICAgICAgIHJfc3NhX2Ukc2Vzb25hbF9zaW4gKyByX3NzYV9lJHNlc29uYWxfY29zICsgcl9zc2FfZSRlDQogICAgICAgICAgICAgICAgICAgICAgICkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCg0KZGF0YSRjb3NfZXJyWzNdIDwtIG1zZSh5MSwgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX3NpbikgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbM10gPC0gbXNlKHkyLCByX2ZmdF9ncm91cGVkJHNlc29uYWxfY29zKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkZV9lcnJbM10gPC0gbXNlKHkzLCByX2ZmdF9ncm91cGVkJGUpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzNdIDwtIG1zZSh5MSArIHkyICsgeTMsIA0KICAgICAgICAgICAgICAgICAgICAgICByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luICsgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX2NvcyArIHJfZmZ0X2dyb3VwZWQkZSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCg0KZGF0YSRjb3NfZXJyWzRdIDwtIG1zZSh5MSwgcl9jaXNzYV9ncm91cGVkJHNlc29uYWxfc2luKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbNF0gPC0gbXNlKHkyLCByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9jb3MpIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkZV9lcnJbNF0gPC0gbXNlKHkzLCByX2Npc3NhX2dyb3VwZWQkZSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbNF0gPC0gbXNlKHkxICsgeTIgKyB5MywgDQogICAgICAgICAgICAgICAgICAgICAgIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX3NpbiArIA0KICAgICAgICAgICAgICAgICAgICAgICAgIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX2NvcyArIA0KICAgICAgICAgICAgICAgICAgICAgICAgIHJfY2lzc2FfZ3JvdXBlZCRlDQogICAgICAgICAgICAgICAgICAgICAgICkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCmRhdGEkY29zX2Vycls1XSA8LSBtc2UoeTEsIHJfY2lzc2FfZ3JvdXBlZF9leHQkc2Vzb25hbF9zaW4pIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkc2luX2Vycls1XSA8LSBtc2UoeTIsIHJfY2lzc2FfZ3JvdXBlZF9leHQkc2Vzb25hbF9jb3MpIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkZV9lcnJbNV0gPC0gbXNlKHkzLCByX2Npc3NhX2dyb3VwZWRfZXh0JGUpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzVdIDwtIG1zZSh5MSArIHkyICsgeTMsIA0KICAgICAgICAgICAgICAgICAgICAgICByX2Npc3NhX2dyb3VwZWRfZXh0JHNlc29uYWxfc2luICsgDQogICAgICAgICAgICAgICAgICAgICAgICAgcl9jaXNzYV9ncm91cGVkX2V4dCRzZXNvbmFsX2NvcyArDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJfY2lzc2FfZ3JvdXBlZF9leHQkZQ0KICAgICAgICAgICAgICAgICAgICAgICApIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQpkYXRhJGNvc19lcnJbNl0gPC0gbXNlKHkxLCByX2ZmdF9ncm91cGVkX2V4dGVuZGVkJHNlc29uYWxfc2luKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbNl0gPC0gbXNlKHkyLCByX2ZmdF9ncm91cGVkX2V4dGVuZGVkJHNlc29uYWxfY29zKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGVfZXJyWzZdIDwtIG1zZSh5Mywgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRlKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2Vycls2XSA8LSBtc2UoeTEgKyB5MiArIHkzLCANCiAgICAgICAgICAgICAgICAgICAgICAgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX3NpbiArDQogICAgICAgICAgICAgICAgICAgICAgICAgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX2NvcyArDQogICAgICAgICAgICAgICAgICAgICAgICAgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRlDQogICAgICAgICAgICAgICAgICAgICAgICkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCg0KDQp0YWJsZV9sYXRleCA8LSB4dGFibGUoZGF0YSwgY2FwdGlvbiA9ICJFeGFtcGxlIFRhYmxlIikNCg0KIyDQqNCw0LMgNDog0JLRi9Cy0L7QtCDRgtCw0LHQu9C40YbRiyDQsiBMYVRlWCDRhNCw0LnQuw0KcHJpbnQodGFibGVfbGF0ZXgsIGluY2x1ZGUucm93bmFtZXMgPSBGQUxTRSkNCg0KYGBgDQoNCiMg0J3QtdGB0LrQvtC70YzQutC+INC90LXQv9C10YDQuNC+0LTQuNC6DQoNCmBgYHtyfQ0KbiA8LSA5NioyDQp4IDwtIDA6KG4tMSkNCkwgPC0gOTYNCnkxIDwtIHNpbigyKnBpLzEyICogeCkNCnkyIDwtIGNvcygyKnBpLzMgKiB4KS8yDQp5MyA8LSBleHAoeC8xMDApICsgMQ0KeSA8LSB5MSArIHkyICsgeTMNCmVwcyA8LSAxLyhuKzEpDQoNCnNfc3NhIDwtIHNzYSh5WzE6KG4tMSldLCBMKQ0Kcl9zc2EgPC0gcmVjb25zdHJ1Y3Qoc19zc2EsIGdyb3Vwcz1saXN0KA0KICBlID0gYygxKSwNCiAgc2Vzb25hbF9zaW4gPSBjKDIsIDMpLA0KICBzZXNvbmFsX2NvcyA9IGMoNCwgNSkNCikpDQojIHBsb3QoeFsxOihuLTEpXSwgcl9zc2EkZSwgdHlwZSA9ICJsIikNCiMgcGxvdCh4WzE6KG4tMSldLCByX3NzYSRzZXNvbmFsX3NpbiwgdHlwZSA9ICJsIikNCiMgcGxvdCh4WzE6KG4tMSldLCByX3NzYSRzZXNvbmFsX2NvcywgdHlwZSA9ICJsIikNCiMgcGxvdCh3Y29yKHNfc3NhLCBncm91cHMgPSAxOjEwKSwgc2NhbGVzID0gbGlzdChhdCA9IGMoMTAsIDIwLCAzMCkpKQ0KZV9zc2EgPC0gZW9zc2FfbmV3KHNfc3NhLCBuZXN0ZWQuZ3JvdXBzID0gbGlzdCgxOjEwKSwgY2x1c3RfdHlwZSA9ICJkaXN0YW5jZSIpDQpnX3Nlc29uYWxfZSA8LSBncm91cGluZy5hdXRvKGVfc3NhLCBiYXNlID0gImVpZ2VuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgZnJlcS5iaW5zID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICAgICBlID0gYygwLCAxLzEyLWVwcy1lcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksDQogICAgICAgICAgICAgICAgICAgICAgIHRocmVzaG9sZCA9IDAuNSkNCnJfc3NhX2UgPC0gcmVjb25zdHJ1Y3QoZV9zc2EsIGdyb3Vwcz1nX3Nlc29uYWxfZSkNCnJfc3NhX2UNCiMgcGxvdCh4LCByX3NzYV9lJHNlc29uYWxfc2luKQ0KIyBwbG90KHgsIHJfc3NhX2Ukc2Vzb25hbF9jb3MpDQoNCg0KDQpyX2ZmdCA8LSByZWNvbnN0cnVjdF9mZnQoeCwgeSkNCnJfZmZ0X2dyb3VwZWQgPC0gZ3JvdXBpbmdfY2lzc2Eocl9mZnQsDQogICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgZSA9IGMoMCwgMS8xMi1lcHMtZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICApJHRfc2VyaWVzDQoNCnJfZmZ0X2V4dGVuZGVkIDwtIHJlY29uc3RydWN0X2ZmdCh4LCB5LCBUUlVFKQ0Kcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCA8LSBncm91cGluZ19jaXNzYShyX2ZmdF9leHRlbmRlZCwNCiAgICAgICAgICAgICAgICAgICAgZ3JvdXBzID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICBlID0gYygwLCAxLzEyLWVwcy1lcHMpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICkkdF9zZXJpZXMNCg0KIyByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luIHw+IGxlbmd0aCgpDQoNCiMgcGxvdCh4LCByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luKQ0KIyBwbG90KHgsIHJfZmZ0X2dyb3VwZWQkc2Vzb25hbF9jb3MpDQojIHBsb3QoeCwgcl9mZnRfZ3JvdXBlZCRyZXNpZHVhbHMpDQoNCg0Kcl9jaXNzYSA8LSBjaXJjdWxhbnRfU1NBKHksIEwpDQpyX2Npc3NhX2dyb3VwZWQgPC0gZ3JvdXBpbmdfY2lzc2Eocl9jaXNzYSwNCiAgICAgICAgICAgICAgICAgICAgZ3JvdXBzID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICBlID0gYygwLCAxLzEyLWVwcy1lcHMpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICkkdF9zZXJpZXMNCg0KDQpyX2Npc3NhX2V4dCA8LSBjaXJjdWxhbnRfU1NBKHksIEwsIGV4dGVuZF9mbGFnID0gVFJVRSkNCnJfY2lzc2FfZ3JvdXBlZF9leHQgPC0gZ3JvdXBpbmdfY2lzc2Eocl9jaXNzYV9leHQsDQogICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgZSA9IGMoMCwgMS8xMi1lcHMtZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICApJHRfc2VyaWVzDQoNCiMgcGxvdCh4LCByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9zaW4pDQojIHBsb3QoeCwgcl9jaXNzYV9ncm91cGVkJHNlc29uYWxfY29zKQ0KIyBwbG90KHgsIHJfY2lzc2FfZ3JvdXBlZCRyZXNpZHVhbHMpDQoNCmxpYnJhcnkoeHRhYmxlKQ0KDQojINCo0LDQsyAyOiDQodC+0LfQtNCw0L3QuNC1INC/0YDQuNC80LXRgNCwINC00LDQvdC90YvRhQ0KZGF0YSA8LSBkYXRhLmZyYW1lKA0KICDQnNC10YLQvtC0ID0gYygiU1NBIiwgIlNTQSBFT1NTQSIsIkZvdXJpZXIiLCAiQ2lTU0EiLCAiQ2lTU0EgZXh0ZW5kZWQiLCAiRm91cmllciBleHRlbmRlZCIpLA0KICBlX2VyciA9IGMoMSwgMSwgMSwgMSwgMSwgMSksDQogIHNpbl9lcnIgPSBjICgxLCAyMCwgMjAsIDEsIDEsIDEpLA0KICBjb3NfZXJyID0gYygxLCAxLCAxLCAxLCAxLCAxKSwNCiAgYWxsX2VyciA9IGMoMSwgMSwgMSwgMSwgMSwgMSkNCikNCg0KZGF0YSRjb3NfZXJyWzFdIDwtIG1zZSh5MVsxOihuLTEpXSwgcl9zc2Ekc2Vzb25hbF9zaW4pIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzFdIDwtIG1zZSh5MlsxOihuLTEpXSwgcl9zc2Ekc2Vzb25hbF9jb3MpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRlX2VyclsxXSA8LSBtc2UoeTNbMToobi0xKV0sIHJfc3NhJGUpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzFdIDwtIG1zZSh5MVsxOihuLTEpXSsgeTJbMToobi0xKV0gKyB5M1sxOihuLTEpXSwNCiAgICAgICAgICAgICAgICAgICAgIHJfc3NhJHNlc29uYWxfc2luICsgcl9zc2Ekc2Vzb25hbF9jb3MgKyByX3NzYSRlKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCg0KZGF0YSRjb3NfZXJyWzJdIDwtIG1zZSh5MVsxOihuLTEpXSwgcl9zc2FfZSRzZXNvbmFsX3NpbikgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbMl0gPC0gbXNlKHkyWzE6KG4tMSldLCByX3NzYV9lJHNlc29uYWxfY29zKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkZV9lcnJbMl0gPC0gbXNlKHkzWzE6KG4tMSldLCByX3NzYV9lJGUpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzJdIDwtIG1zZSh5MVsxOihuLTEpXSsgeTJbMToobi0xKV0gKyB5M1sxOihuLTEpXSwNCiAgICAgICAgICAgICAgICAgICAgIHJfc3NhX2Ukc2Vzb25hbF9zaW4gKyByX3NzYV9lJHNlc29uYWxfY29zICsgcl9zc2FfZSRlDQogICAgICAgICAgICAgICAgICAgICAgICkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCg0KZGF0YSRjb3NfZXJyWzNdIDwtIG1zZSh5MSwgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX3NpbikgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbM10gPC0gbXNlKHkyLCByX2ZmdF9ncm91cGVkJHNlc29uYWxfY29zKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkZV9lcnJbM10gPC0gbXNlKHkzLCByX2ZmdF9ncm91cGVkJGUpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzNdIDwtIG1zZSh5MSArIHkyICsgeTMsIA0KICAgICAgICAgICAgICAgICAgICAgICByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luICsgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX2NvcyArIHJfZmZ0X2dyb3VwZWQkZSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCg0KZGF0YSRjb3NfZXJyWzRdIDwtIG1zZSh5MSwgcl9jaXNzYV9ncm91cGVkJHNlc29uYWxfc2luKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbNF0gPC0gbXNlKHkyLCByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9jb3MpIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkZV9lcnJbNF0gPC0gbXNlKHkzLCByX2Npc3NhX2dyb3VwZWQkZSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbNF0gPC0gbXNlKHkxICsgeTIgKyB5MywgDQogICAgICAgICAgICAgICAgICAgICAgIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX3NpbiArIA0KICAgICAgICAgICAgICAgICAgICAgICAgIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX2NvcyArIA0KICAgICAgICAgICAgICAgICAgICAgICAgIHJfY2lzc2FfZ3JvdXBlZCRlDQogICAgICAgICAgICAgICAgICAgICAgICkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCmRhdGEkY29zX2Vycls1XSA8LSBtc2UoeTEsIHJfY2lzc2FfZ3JvdXBlZF9leHQkc2Vzb25hbF9zaW4pIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkc2luX2Vycls1XSA8LSBtc2UoeTIsIHJfY2lzc2FfZ3JvdXBlZF9leHQkc2Vzb25hbF9jb3MpIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkZV9lcnJbNV0gPC0gbXNlKHkzLCByX2Npc3NhX2dyb3VwZWRfZXh0JGUpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzVdIDwtIG1zZSh5MSArIHkyICsgeTMsIA0KICAgICAgICAgICAgICAgICAgICAgICByX2Npc3NhX2dyb3VwZWRfZXh0JHNlc29uYWxfc2luICsgDQogICAgICAgICAgICAgICAgICAgICAgICAgcl9jaXNzYV9ncm91cGVkX2V4dCRzZXNvbmFsX2NvcyArDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJfY2lzc2FfZ3JvdXBlZF9leHQkZQ0KICAgICAgICAgICAgICAgICAgICAgICApIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQpkYXRhJGNvc19lcnJbNl0gPC0gbXNlKHkxLCByX2ZmdF9ncm91cGVkX2V4dGVuZGVkJHNlc29uYWxfc2luKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbNl0gPC0gbXNlKHkyLCByX2ZmdF9ncm91cGVkX2V4dGVuZGVkJHNlc29uYWxfY29zKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGVfZXJyWzZdIDwtIG1zZSh5Mywgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRlKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2Vycls2XSA8LSBtc2UoeTEgKyB5MiArIHkzLCANCiAgICAgICAgICAgICAgICAgICAgICAgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX3NpbiArDQogICAgICAgICAgICAgICAgICAgICAgICAgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX2NvcyArDQogICAgICAgICAgICAgICAgICAgICAgICAgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRlDQogICAgICAgICAgICAgICAgICAgICAgICkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCg0KDQp0YWJsZV9sYXRleCA8LSB4dGFibGUoZGF0YSwgY2FwdGlvbiA9ICJFeGFtcGxlIFRhYmxlIikNCg0KIyDQqNCw0LMgNDog0JLRi9Cy0L7QtCDRgtCw0LHQu9C40YbRiyDQsiBMYVRlWCDRhNCw0LnQuw0KcHJpbnQodGFibGVfbGF0ZXgsIGluY2x1ZGUucm93bmFtZXMgPSBGQUxTRSkNCmBgYA0KDQojINCS0YvQtNC10LvQtdC90LjQtSDRgtGA0LXQvdC00LANCg0KYGBge3J9DQpuIDwtIDk2KjINCnggPC0gMDoobi0xKQ0KTCA8LSA5Ng0KeTEgPC0gc2luKDIqcGkvMTIgKiB4KQ0KeTIgPC0gY29zKDIqcGkvMyAqIHgpLzINCnkzIDwtIGV4cCh4LzEwMCkgKyAxDQp5IDwtIHkxICsgeTIgKyB5Mw0KZXBzIDwtIDEvKG4rMSkNCg0Kc19zc2EgPC0gc3NhKHksIEwpDQpyX3NzYSA8LSByZWNvbnN0cnVjdChzX3NzYSwgZ3JvdXBzPWxpc3QoDQogIGUgPSBjKDEsIDYpLA0KICBzZXNvbmFsX3NpbiA9IGMoMiwgMyksDQogIHNlc29uYWxfY29zID0gYyg0LCA1KSwNCiAgYWxsID0gMTo2DQopKQ0KIyBwbG90KHhbMToobi0xKV0sIHJfc3NhJGUsIHR5cGUgPSAibCIpDQojIHBsb3QoeFsxOihuLTEpXSwgcl9zc2Ekc2Vzb25hbF9zaW4sIHR5cGUgPSAibCIpDQojIHBsb3QoeFsxOihuLTEpXSwgcl9zc2Ekc2Vzb25hbF9jb3MsIHR5cGUgPSAibCIpDQojIHBsb3Qod2NvcihzX3NzYSwgZ3JvdXBzID0gMToxMCksIHNjYWxlcyA9IGxpc3QoYXQgPSBjKDEwLCAyMCwgMzApKSkNCmVfc3NhIDwtIGVvc3NhX25ldyhzX3NzYSwgbmVzdGVkLmdyb3VwcyA9IGxpc3QoMTo2KSwgY2x1c3RfdHlwZSA9ICJkaXN0YW5jZSIpDQpnX3Nlc29uYWxfZSA8LSBncm91cGluZy5hdXRvKGVfc3NhLCBiYXNlID0gImVpZ2VuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgZnJlcS5iaW5zID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICAgICBlID0gYygwLCAxLzEyLWVwcy1lcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksDQogICAgICAgICAgICAgICAgICAgICAgIHRocmVzaG9sZCA9IDAuNSkNCnJfc3NhX2UgPC0gcmVjb25zdHJ1Y3QoZV9zc2EsIGdyb3Vwcz1nX3Nlc29uYWxfZSkNCiMgcGxvdCh4LCByX3NzYV9lJHNlc29uYWxfc2luKQ0KIyBwbG90KHgsIHJfc3NhX2Ukc2Vzb25hbF9jb3MpDQoNCg0KDQpyX2ZmdCA8LSByZWNvbnN0cnVjdF9mZnQoeFsxOihuLTEpXSwgeVsxOihuLTEpXSkNCnJfZmZ0X2dyb3VwZWQgPC0gZ3JvdXBpbmdfY2lzc2Eocl9mZnQsDQogICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgZSA9IGMoMCwgMS8xMi1lcHMtZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICApJHRfc2VyaWVzDQoNCnJfZmZ0X2V4dGVuZGVkIDwtIHJlY29uc3RydWN0X2ZmdCh4WzE6KG4tMSldLCB5WzE6KG4tMSldLCBUUlVFKQ0Kcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCA8LSBncm91cGluZ19jaXNzYShyX2ZmdF9leHRlbmRlZCwNCiAgICAgICAgICAgICAgICAgICAgZ3JvdXBzID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICBlID0gYygwLCAxLzEyLWVwcy1lcHMpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICkkdF9zZXJpZXMNCg0KIyByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luIHw+IGxlbmd0aCgpDQoNCiMgcGxvdCh4LCByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luKQ0KIyBwbG90KHgsIHJfZmZ0X2dyb3VwZWQkc2Vzb25hbF9jb3MpDQojIHBsb3QoeCwgcl9mZnRfZ3JvdXBlZCRyZXNpZHVhbHMpDQoNCg0Kcl9jaXNzYSA8LSBjaXJjdWxhbnRfU1NBKHksIEwrMSkNCnJfY2lzc2FfZ3JvdXBlZCA8LSBncm91cGluZ19jaXNzYShyX2Npc3NhLA0KICAgICAgICAgICAgICAgICAgICBncm91cHMgPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgICAgIGUgPSBjKDAsIDEvMTItZXBzLWVwcyksDQogICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9zaW4gPSBjKDEvMTItZXBzLCAxLzEyK2VwcyksDQogICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9jb3MgPSBjKDEvMy1lcHMsIDEvMytlcHMpDQogICAgICAgICAgICAgICAgICAgICkNCiAgICAgICAgICAgICAgICAgICAgKSR0X3Nlcmllcw0KDQoNCnJfY2lzc2FfZXh0IDwtIGNpcmN1bGFudF9TU0EoeSwgTCsxLCBleHRlbmRfZmxhZyA9IFRSVUUpDQpyX2Npc3NhX2dyb3VwZWRfZXh0IDwtIGdyb3VwaW5nX2Npc3NhKHJfY2lzc2FfZXh0LA0KICAgICAgICAgICAgICAgICAgICBncm91cHMgPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgICAgIGUgPSBjKDAsIDEvMTItZXBzLWVwcyksDQogICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9zaW4gPSBjKDEvMTItZXBzLCAxLzEyK2VwcyksDQogICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9jb3MgPSBjKDEvMy1lcHMsIDEvMytlcHMpDQogICAgICAgICAgICAgICAgICAgICkNCiAgICAgICAgICAgICAgICAgICAgKSR0X3Nlcmllcw0KDQojIHBsb3QoeCwgcl9jaXNzYV9ncm91cGVkJHNlc29uYWxfc2luKQ0KIyBwbG90KHgsIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX2NvcykNCiMgcGxvdCh4LCByX2Npc3NhX2dyb3VwZWQkcmVzaWR1YWxzKQ0KDQpsaWJyYXJ5KHh0YWJsZSkNCg0KIyDQqNCw0LMgMjog0KHQvtC30LTQsNC90LjQtSDQv9GA0LjQvNC10YDQsCDQtNCw0L3QvdGL0YUNCmRhdGEgPC0gZGF0YS5mcmFtZSgNCiAg0JzQtdGC0L7QtCA9IGMoIlNTQSIsICJTU0EgRU9TU0EiLCJGb3VyaWVyIiwgIkNpU1NBIiwgIkNpU1NBIGV4dGVuZGVkIiwgIkZvdXJpZXIgZXh0ZW5kZWQiKSwNCiAgZV9lcnIgPSBjKDEsIDEsIDEsIDEsIDEsIDEpLA0KICBzaW5fZXJyID0gYyAoMSwgMjAsIDIwLCAxLCAxLCAxKSwNCiAgY29zX2VyciA9IGMoMSwgMSwgMSwgMSwgMSwgMSksDQogIGFsbF9lcnIgPSBjKDEsIDEsIDEsIDEsIDEsIDEpDQopDQoNCmRhdGEkY29zX2VyclsxXSA8LSBtc2UoeTEsIHJfc3NhJHNlc29uYWxfc2luKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkc2luX2VyclsxXSA8LSBtc2UoeTIsIHJfc3NhJHNlc29uYWxfY29zKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkZV9lcnJbMV0gPC0gbXNlKHkzLCByX3NzYSRlKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2VyclsxXSA8LSBtc2UoeTErIHkyICsgeTMsDQogICAgICAgICAgICAgICAgICAgICByX3NzYSRhbGwpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQpkYXRhJGNvc19lcnJbMl0gPC0gbXNlKHkxLCByX3NzYV9lJHNlc29uYWxfc2luKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkc2luX2VyclsyXSA8LSBtc2UoeTIsIHJfc3NhX2Ukc2Vzb25hbF9jb3MpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRlX2VyclsyXSA8LSBtc2UoeTMsIHJfc3NhX2UkZSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbMl0gPC0gbXNlKHkxKyB5MiArIHkzLA0KICAgICAgICAgICAgICAgICAgICAgcl9zc2FfZSRzZXNvbmFsX3NpbiArIHJfc3NhX2Ukc2Vzb25hbF9jb3MgKyByX3NzYV9lJGUNCiAgICAgICAgICAgICAgICAgICAgICAgKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCg0KDQpkYXRhJGNvc19lcnJbM10gPC0gbXNlKHkxWzE6KG4tMSldLCByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkc2luX2VyclszXSA8LSBtc2UoeTJbMToobi0xKV0sIHJfZmZ0X2dyb3VwZWQkc2Vzb25hbF9jb3MpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRlX2VyclszXSA8LSBtc2UoeTNbMToobi0xKV0sIHJfZmZ0X2dyb3VwZWQkZSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbM10gPC0gbXNlKCh5MSArIHkyICsgeTMpWzE6KG4tMSldLCANCiAgICAgICAgICAgICAgICAgICAgICAgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX3NpbiArIHJfZmZ0X2dyb3VwZWQkc2Vzb25hbF9jb3MgKyByX2ZmdF9ncm91cGVkJGUpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCmRhdGEkY29zX2Vycls0XSA8LSBtc2UoeTEsIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX3NpbikgfD4gDQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzRdIDwtIG1zZSh5Miwgcl9jaXNzYV9ncm91cGVkJHNlc29uYWxfY29zKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGVfZXJyWzRdIDwtIG1zZSh5Mywgcl9jaXNzYV9ncm91cGVkJGUpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzRdIDwtIG1zZSh5MSArIHkyICsgeTMsIA0KICAgICAgICAgICAgICAgICAgICAgICByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9zaW4gKyANCiAgICAgICAgICAgICAgICAgICAgICAgICByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9jb3MgKyANCiAgICAgICAgICAgICAgICAgICAgICAgICByX2Npc3NhX2dyb3VwZWQkZQ0KICAgICAgICAgICAgICAgICAgICAgICApIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQpkYXRhJGNvc19lcnJbNV0gPC0gbXNlKHkxLCByX2Npc3NhX2dyb3VwZWRfZXh0JHNlc29uYWxfc2luKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbNV0gPC0gbXNlKHkyLCByX2Npc3NhX2dyb3VwZWRfZXh0JHNlc29uYWxfY29zKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGVfZXJyWzVdIDwtIG1zZSh5Mywgcl9jaXNzYV9ncm91cGVkX2V4dCRlKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2Vycls1XSA8LSBtc2UoeTEgKyB5MiArIHkzLCANCiAgICAgICAgICAgICAgICAgICAgICAgcl9jaXNzYV9ncm91cGVkX2V4dCRzZXNvbmFsX3NpbiArIA0KICAgICAgICAgICAgICAgICAgICAgICAgIHJfY2lzc2FfZ3JvdXBlZF9leHQkc2Vzb25hbF9jb3MgKw0KICAgICAgICAgICAgICAgICAgICAgICAgICByX2Npc3NhX2dyb3VwZWRfZXh0JGUNCiAgICAgICAgICAgICAgICAgICAgICAgKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCg0KZGF0YSRjb3NfZXJyWzZdIDwtIG1zZSh5MVsxOihuLTEpXSwgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX3NpbikgfD4gDQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzZdIDwtIG1zZSh5MlsxOihuLTEpXSwgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX2NvcykgfD4gDQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRlX2Vycls2XSA8LSBtc2UoeTNbMToobi0xKV0sIHJfZmZ0X2dyb3VwZWRfZXh0ZW5kZWQkZSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbNl0gPC0gbXNlKCh5MSArIHkyICsgeTMpWzE6KG4tMSldLCANCiAgICAgICAgICAgICAgICAgICAgICAgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX3NpbiArDQogICAgICAgICAgICAgICAgICAgICAgICAgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX2NvcyArDQogICAgICAgICAgICAgICAgICAgICAgICAgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRlDQogICAgICAgICAgICAgICAgICAgICAgICkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCg0KDQp0YWJsZV9sYXRleCA8LSB4dGFibGUoZGF0YSwgY2FwdGlvbiA9ICJFeGFtcGxlIFRhYmxlIikNCg0KIyDQqNCw0LMgNDog0JLRi9Cy0L7QtCDRgtCw0LHQu9C40YbRiyDQsiBMYVRlWCDRhNCw0LnQuw0KcHJpbnQodGFibGVfbGF0ZXgsIGluY2x1ZGUucm93bmFtZXMgPSBGQUxTRSkNCmBgYA0KDQojINCo0KPQnA0KDQojIyBzaW4gY29zDQoNCmBgYHtyfQ0KDQpkYXRhIDwtIGxpc3QoDQogINCc0LXRgtC+0LQgPSBjKCJTU0EiLCJTU0EgRU9TU0EiLCJGb3VyaWVyIiwgIkNpU1NBIiwgIkNpU1NBIGV4dGVuZGVkIiwgIkZvdXJpZXIgZXh0ZW5kZWQiKSwNCiAgc2luX2VyciA9IGxpc3QobGlzdCgpLCBsaXN0KCksIGxpc3QoKSwgbGlzdCgpLCBsaXN0KCksIGxpc3QoKSksDQogIGNvc19lcnIgPSBsaXN0KGxpc3QoKSwgbGlzdCgpLCBsaXN0KCksIGxpc3QoKSwgbGlzdCgpLCBsaXN0KCkpLA0KICBhbGxfZXJyID0gbGlzdChsaXN0KCksIGxpc3QoKSwgbGlzdCgpLCBsaXN0KCksIGxpc3QoKSwgbGlzdCgpKQ0KKQ0KDQpmb3IgKGkgaW4gMToxMDApew0KICBzZXQuc2VlZChpKQ0KICANCiAgbiA8LSA5NioyDQogIEwgPC0gOTYNCiAgeCA8LSAwOihuLTEpDQogIHkxIDwtIHNpbigyKnBpLzEyICogeCkNCiAgeTIgPC0gY29zKDIqcGkvMyAqIHgpLzINCiAgeSA8LSB5MSArIHkyICsgcm5vcm0obiwgMCwgMC4xKQ0KICBYIDwtIGhhbmtlbCh5LCBMID0gTCkNCiAgZXBzIDwtIDEvKG4rMSkNCiAgDQogIHNfc3NhIDwtIHNzYSh5LCBMKQ0KICByX3NzYSA8LSByZWNvbnN0cnVjdChzX3NzYSwgZ3JvdXBzID0gbGlzdCgNCiAgICBGMSA9IGMoMSwgMiksDQogICAgRjIgPSBjKDMsIDQpDQogICkpDQogICMgcl9zc2EgPC0gcmVjb25zdHJ1Y3Qoc19zc2EsIGdyb3Vwcz1saXN0KA0KICAjICAgc2Vzb25hbF9zaW4gPSBjKDEsIDIpLA0KICAjICAgc2Vzb25hbF9jb3MgPSBjKDMsIDQpDQogICMgKSkNCiAgIyBwbG90KHhbMToobi0xKV0sIHJfc3NhJEYxLCB0eXBlID0gImwiKQ0KICAjIHBsb3QoeFsxOihuLTEpXSwgcl9zc2EkRjIsIHR5cGUgPSAibCIpDQogICMgcGxvdCh3Y29yKHNfc3NhLCBncm91cHMgPSAxOjEwKSwgc2NhbGVzID0gbGlzdChhdCA9IGMoMTAsIDIwLCAzMCkpKQ0KICBlX3NzYSA8LSBlb3NzYV9uZXcoc19zc2EsIG5lc3RlZC5ncm91cHMgPSBsaXN0KDE6NCksIGNsdXN0X3R5cGUgPSAiZGlzdGFuY2UiKQ0KICBnX3Nlc29uYWxfZSA8LSBncm91cGluZy5hdXRvKGVfc3NhLCBiYXNlID0gImVpZ2VuIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICBmcmVxLmJpbnMgPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9zaW4gPSBjKDEvMTItZXBzLCAxLzEyK2VwcyksDQogICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksDQogICAgICAgICAgICAgICAgICAgICAgICAgdGhyZXNob2xkID0gMC41KQ0KICByX3NzYV9lIDwtIHJlY29uc3RydWN0KGVfc3NhLCBncm91cHM9Z19zZXNvbmFsX2UpDQogICMgcGxvdCh4LCByX3NzYV9lJHNlc29uYWxfc2luKQ0KICAjIHBsb3QoeCwgcl9zc2FfZSRzZXNvbmFsX2NvcykNCiAgDQogIA0KICANCiAgcl9mZnQgPC0gcmVjb25zdHJ1Y3RfZmZ0KHhbMToobi0xKV0sIHlbMToobi0xKV0pDQogIHJfZmZ0X2dyb3VwZWQgPC0gZ3JvdXBpbmdfY2lzc2Eocl9mZnQsDQogICAgICAgICAgICAgICAgICAgICAgZ3JvdXBzID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9jb3MgPSBjKDEvMy1lcHMsIDEvMytlcHMpDQogICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICAgICkkdF9zZXJpZXMNCiAgDQogIHJfZmZ0X2V4dGVuZGVkIDwtIHJlY29uc3RydWN0X2ZmdCh4WzE6KG4tMSldLCB5WzE6KG4tMSldLCBUUlVFKQ0KICByX2ZmdF9ncm91cGVkX2V4dGVuZGVkIDwtIGdyb3VwaW5nX2Npc3NhKHJfZmZ0X2V4dGVuZGVkLA0KICAgICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICAgICkNCiAgICAgICAgICAgICAgICAgICAgICApJHRfc2VyaWVzDQogIA0KICAjIHJfZmZ0X2dyb3VwZWQkc2Vzb25hbF9zaW4gfD4gbGVuZ3RoKCkNCiAgDQogICMgcGxvdCh4LCByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luKQ0KICAjIHBsb3QoeCwgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX2NvcykNCiAgIyBwbG90KHgsIHJfZmZ0X2dyb3VwZWQkcmVzaWR1YWxzKQ0KICANCiAgDQogIHJfY2lzc2EgPC0gY2lyY3VsYW50X1NTQSh5LCBMKzEpDQogIHJfY2lzc2FfZ3JvdXBlZCA8LSBncm91cGluZ19jaXNzYShyX2Npc3NhLA0KICAgICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICAgICkNCiAgICAgICAgICAgICAgICAgICAgICApJHRfc2VyaWVzDQogIA0KICANCiAgcl9jaXNzYV9leHQgPC0gY2lyY3VsYW50X1NTQSh5LCBMKzEsIGV4dGVuZF9mbGFnID0gVFJVRSkNCiAgcl9jaXNzYV9ncm91cGVkX2V4dCA8LSBncm91cGluZ19jaXNzYShyX2Npc3NhX2V4dCwNCiAgICAgICAgICAgICAgICAgICAgICBncm91cHMgPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9zaW4gPSBjKDEvMTItZXBzLCAxLzEyK2VwcyksDQogICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgKSR0X3Nlcmllcw0KICBkYXRhJGNvc19lcnJbWzFdXVtbaV1dIDwtIA0KICAgIG1pbihtc2UoeTEsIHJfc3NhJEYxKSwgbXNlKHkxLCByX3NzYSRGMikpDQogIGRhdGEkc2luX2VycltbMV1dW1tpXV0gPC0NCiAgICBtaW4obXNlKHkyLCByX3NzYSRGMSksIG1zZSh5Miwgcl9zc2EkRjIpKQ0KICBkYXRhJGFsbF9lcnJbWzFdXVtbaV1dIDwtDQogICAgbWluKG1zZSh5MSt5Miwgcl9zc2EkRjErIHJfc3NhJEYyKSkNCiAgDQogIGRhdGEkY29zX2VycltbMl1dW1tpXV0gPC0gbXNlKHkxLCByX3NzYV9lJHNlc29uYWxfc2luKQ0KICBkYXRhJHNpbl9lcnJbWzJdXVtbaV1dIDwtIG1zZSh5Miwgcl9zc2FfZSRzZXNvbmFsX2NvcykNCiAgZGF0YSRhbGxfZXJyW1syXV1bW2ldXSA8LSBtc2UoeTErIHkyLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByX3NzYV9lJHNlc29uYWxfc2luICsgcl9zc2FfZSRzZXNvbmFsX2NvcykNCiAgDQogIA0KICBkYXRhJGNvc19lcnJbWzNdXVtbaV1dIDwtIG1zZSh5MVsxOihuLTEpXSwgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX3NpbikNCiAgZGF0YSRzaW5fZXJyW1szXV1bW2ldXSA8LSBtc2UoeTJbMToobi0xKV0sIHJfZmZ0X2dyb3VwZWQkc2Vzb25hbF9jb3MpDQogIGRhdGEkYWxsX2VycltbM11dW1tpXV0gPC0gbXNlKCh5MSArIHkyKVsxOihuLTEpXSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX2NvcyArICByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luKQ0KICANCiAgDQogIGRhdGEkY29zX2VycltbNF1dW1tpXV0gPC0gbXNlKHkxLCByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9zaW4pDQogIGRhdGEkc2luX2VycltbNF1dW1tpXV0gPC0gbXNlKHkyLCByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9jb3MpDQogIGRhdGEkYWxsX2VycltbNF1dW1tpXV0gPC0gbXNlKHkxICsgeTIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX3NpbiArICByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9jb3MNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICANCiAgZGF0YSRjb3NfZXJyW1s1XV1bW2ldXSA8LSBtc2UoeTEsIHJfY2lzc2FfZ3JvdXBlZF9leHQkc2Vzb25hbF9zaW4pDQogIGRhdGEkc2luX2VycltbNV1dW1tpXV0gPC0gbXNlKHkyLCByX2Npc3NhX2dyb3VwZWRfZXh0JHNlc29uYWxfY29zKQ0KICBkYXRhJGFsbF9lcnJbWzVdXVtbaV1dIDwtIG1zZSh5MSArIHkyLA0KICAgICAgICAgICAgICAgICAgICAgICAgICByX2Npc3NhX2dyb3VwZWRfZXh0JHNlc29uYWxfc2luICsgcl9jaXNzYV9ncm91cGVkX2V4dCRzZXNvbmFsX2Nvcw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQogIA0KICBkYXRhJGNvc19lcnJbWzZdXVtbaV1dIDwtIG1zZSh5MVsxOihuLTEpXSwgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX3NpbikNCiAgZGF0YSRzaW5fZXJyW1s2XV1bW2ldXSA8LSBtc2UoeTJbMToobi0xKV0sIHJfZmZ0X2dyb3VwZWRfZXh0ZW5kZWQkc2Vzb25hbF9jb3MpDQogIGRhdGEkYWxsX2VycltbNl1dW1tpXV0gPC0gbXNlKCh5MSArIHkyKVsxOihuLTEpXSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX3NpbiArIHJfZmZ0X2dyb3VwZWRfZXh0ZW5kZWQkc2Vzb25hbF9jb3MNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KfQ0KbGlicmFyeSh4dGFibGUpDQoNCiMg0KjQsNCzIDI6INCh0L7Qt9C00LDQvdC40LUg0L/RgNC40LzQtdGA0LAg0LTQsNC90L3Ri9GFDQpkYXRhX3ByZXYgPC0gZGF0YQ0KDQpkYXRhIDwtIGRhdGEuZnJhbWUoDQogINCc0LXRgtC+0LQgPSBjKCJTU0EiLCAiU1NBIEVPU1NBIiwiRm91cmllciIsICJDaVNTQSIsICJDaVNTQSBleHRlbmRlZCIsICJGb3VyaWVyIGV4dGVuZGVkIiksDQogIHNpbl9lcnIgPSBjKDAsIDAsIDAsIDAsIDAsIDApLA0KICBjb3NfZXJyID0gYygwLCAwLCAwLCAwLCAwLCAwKSwNCiAgYWxsX2VyciA9IGMoMCwgMCwgMCwgMCwgMCwgMCkNCikNCg0KZGF0YSRjb3NfZXJyWzFdIDwtIG1lYW4oZGF0YV9wcmV2JGNvc19lcnJbWzFdXSB8PiB1bmxpc3QoKSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbMV0gPC0gbWVhbihkYXRhX3ByZXYkc2luX2VycltbMV1dfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzFdIDwtIG1lYW4oZGF0YV9wcmV2JGFsbF9lcnJbWzFdXXw+IHVubGlzdCgpKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCg0KZGF0YSRjb3NfZXJyWzJdIDwtIG1lYW4oZGF0YV9wcmV2JGNvc19lcnJbWzJdXSB8PiB1bmxpc3QoKSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbMl0gPC0gbWVhbihkYXRhX3ByZXYkc2luX2VycltbMl1dfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzJdIDwtIG1lYW4oZGF0YV9wcmV2JGFsbF9lcnJbWzJdXXw+IHVubGlzdCgpKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCg0KDQpkYXRhJGNvc19lcnJbM10gPC0gbWVhbihkYXRhX3ByZXYkY29zX2VycltbM11dfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzNdIDwtIG1lYW4oZGF0YV9wcmV2JHNpbl9lcnJbWzNdXXw+IHVubGlzdCgpKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2VyclszXSA8LSBtZWFuKGRhdGFfcHJldiRhbGxfZXJyW1szXV18PiB1bmxpc3QoKSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCg0KZGF0YSRjb3NfZXJyWzRdIDwtIG1lYW4oZGF0YV9wcmV2JGNvc19lcnJbWzRdXXw+IHVubGlzdCgpKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbNF0gPC0gbWVhbihkYXRhX3ByZXYkc2luX2VycltbNF1dfD4gdW5saXN0KCkpIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2Vycls0XSA8LSBtZWFuKGRhdGFfcHJldiRhbGxfZXJyW1s0XV18PiB1bmxpc3QoKSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCg0KZGF0YSRjb3NfZXJyWzVdIDwtIG1lYW4oZGF0YV9wcmV2JGNvc19lcnJbWzVdXXw+IHVubGlzdCgpKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbNV0gPC0gbWVhbihkYXRhX3ByZXYkc2luX2VycltbNV1dfD4gdW5saXN0KCkpIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2Vycls1XSA8LSBtZWFuKGRhdGFfcHJldiRhbGxfZXJyW1s1XV18PiB1bmxpc3QoKSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCmRhdGEkY29zX2Vycls2XSA8LSBtZWFuKGRhdGFfcHJldiRjb3NfZXJyW1s2XV18PiB1bmxpc3QoKSkgfD4gDQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzZdIDwtIG1lYW4oZGF0YV9wcmV2JHNpbl9lcnJbWzZdXXw+IHVubGlzdCgpKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbNl0gPC0gbWVhbihkYXRhX3ByZXYkYWxsX2VycltbNl1dfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQpgYGANCg0KYGBge3J9DQpmb3IgKGkgaW4gMTo2KXsNCiAgZm9yIChqIGluIChpKTo2KXsNCiAgICB4IDwtIGRhdGFfcHJldiRjb3NfZXJyW1tpXV0gfD4gdW5saXN0KCkNCiAgICB5IDwtIGRhdGFfcHJldiRjb3NfZXJyW1tqXV0gfD4gdW5saXN0KCkNCiAgICB0X3Rlc3RfcmVzdWx0IDwtIHQudGVzdCh4LCB5LCBwYWlyZWQgPSBUUlVFKQ0KICAgIHByaW50KHBhc3RlKCJjb3MsICIsIGRhdGEk0JzQtdGC0L7QtFtpXSwgIiAiLCBkYXRhJNCc0LXRgtC+0LRbal0sICIsIHAtdmFsID0gIiwgdF90ZXN0X3Jlc3VsdCRwLnZhbHVlKSkNCiAgfQ0KfQ0KDQpmb3IgKGkgaW4gMTo2KXsNCiAgZm9yIChqIGluIChpKTo2KXsNCiAgICB4IDwtIGRhdGFfcHJldiRzaW5fZXJyW1tpXV0gfD4gdW5saXN0KCkNCiAgICB5IDwtIGRhdGFfcHJldiRzaW5fZXJyW1tqXV0gfD4gdW5saXN0KCkNCiAgICB0X3Rlc3RfcmVzdWx0IDwtIHQudGVzdCh4LCB5LCBwYWlyZWQgPSBUUlVFKQ0KICAgIHByaW50KHBhc3RlKCJzaW4sICIsIGRhdGEk0JzQtdGC0L7QtFtpXSwgIiAiLCBkYXRhJNCc0LXRgtC+0LRbal0sICIsIHAtdmFsID0gIiwgdF90ZXN0X3Jlc3VsdCRwLnZhbHVlKSkNCiAgfQ0KfQ0KDQpmb3IgKGkgaW4gMTo2KXsNCiAgZm9yIChqIGluIChpKTo2KXsNCiAgICB4IDwtIGRhdGFfcHJldiRhbGxfZXJyW1tpXV0gfD4gdW5saXN0KCkNCiAgICB5IDwtIGRhdGFfcHJldiRhbGxfZXJyW1tqXV0gfD4gdW5saXN0KCkNCiAgICB0X3Rlc3RfcmVzdWx0IDwtIHQudGVzdCh4LCB5LCBwYWlyZWQgPSBUUlVFKQ0KICAgIHByaW50KHBhc3RlKCJhbGxfZXJyLCAiLCBkYXRhJNCc0LXRgtC+0LRbaV0sICIgIiwgZGF0YSTQnNC10YLQvtC0W2pdLCAiLCBwLXZhbCA9ICIsIHRfdGVzdF9yZXN1bHQkcC52YWx1ZSkpDQogIH0NCn0NCg0KDQp0YWJsZV9sYXRleCA8LSB4dGFibGUoZGF0YSwgY2FwdGlvbiA9ICJFeGFtcGxlIFRhYmxlIikNCg0KIyDQqNCw0LMgNDog0JLRi9Cy0L7QtCDRgtCw0LHQu9C40YbRiyDQsiBMYVRlWCDRhNCw0LnQuw0KcHJpbnQodGFibGVfbGF0ZXgsIGluY2x1ZGUucm93bmFtZXMgPSBGQUxTRSkNCg0KIyBtZWFuKGRhdGFfcHJldiRzaW5fZXJyW1syXV0gfD4gdW5saXN0KCkpIHw+IHByaW50KCkNCiMgbWVhbihkYXRhX3ByZXYkc2luX2VycltbMV1dIHw+IHVubGlzdCgpKSB8PiBwcmludCgpDQpgYGANCg0KIyMgc2luIGNvcyB0cmVuZA0KDQpgYGB7cn0NCmRhdGEgPC0gbGlzdCgNCiAg0JzQtdGC0L7QtCA9IGMoIlNTQSIsICJTU0EgRU9TU0EiLCJGb3VyaWVyIiwgIkNpU1NBIiwgIkNpU1NBIGV4dGVuZGVkIiwgIkZvdXJpZXIgZXh0ZW5kZWQiKSwNCiAgc2luX2VyciA9IGxpc3QobGlzdCgpLCBsaXN0KCksIGxpc3QoKSwgbGlzdCgpLCBsaXN0KCksIGxpc3QoKSksDQogIGNvc19lcnIgPSBsaXN0KGxpc3QoKSwgbGlzdCgpLCBsaXN0KCksIGxpc3QoKSwgbGlzdCgpLCBsaXN0KCkpLA0KICBleHBfZXJyID0gbGlzdChsaXN0KCksIGxpc3QoKSwgbGlzdCgpLCBsaXN0KCksIGxpc3QoKSwgbGlzdCgpKSwNCiAgYWxsX2VyciA9IGxpc3QobGlzdCgpLCBsaXN0KCksIGxpc3QoKSwgbGlzdCgpLCBsaXN0KCksIGxpc3QoKSkNCikNCg0KZm9yIChpIGluIDE6MTAwKXsNCiAgc2V0LnNlZWQoaSkNCiAgDQogIG4gPC0gOTYqMg0KICB4IDwtIDA6KG4tMSkNCiAgTCA8LSA5Ng0KICB5MSA8LSBzaW4oMipwaS8xMiAqIHgpDQogIHkyIDwtIGNvcygyKnBpLzMgKiB4KS8yDQogIHkzIDwtIGV4cCh4LzEwMCkgKyAxDQogIHkgPC0geTEgKyB5MiArIHkzICsgcm5vcm0obiwgMCwgMC4xKQ0KICBlcHMgPC0gMS8obisxKQ0KICANCiAgc19zc2EgPC0gc3NhKHksIEwpDQogIHJfc3NhIDwtIHJlY29uc3RydWN0KHNfc3NhLCBncm91cHM9bGlzdCgNCiAgICBlID0gMSwNCiAgICBzZXNvbmFsX3NpbiA9IGMoMiwgMyksDQogICAgc2Vzb25hbF9jb3MgPSBjKDQsIDUpDQogICkpDQogIA0KICANCiAgZV9zc2EgPC0gZW9zc2FfbmV3KHNfc3NhLCBuZXN0ZWQuZ3JvdXBzID0gbGlzdCgxOjcpLCBjbHVzdF90eXBlID0gImRpc3RhbmNlIikNCiAgZ19zZXNvbmFsX2UgPC0gZ3JvdXBpbmcuYXV0byhlX3NzYSwgYmFzZSA9ICJlaWdlbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgZnJlcS5iaW5zID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGUgPSBjKDAsIDEvMTItZXBzLWVwcyksDQogICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICB0aHJlc2hvbGQgPSAwLjUpDQogIHJfc3NhX2UgPC0gcmVjb25zdHJ1Y3QoZV9zc2EsIGdyb3Vwcz1nX3Nlc29uYWxfZSkNCiAgDQogIA0KICANCiAgcl9mZnQgPC0gcmVjb25zdHJ1Y3RfZmZ0KHhbMToobi0xKV0sIHlbMToobi0xKV0pDQogIHJfZmZ0X2dyb3VwZWQgPC0gZ3JvdXBpbmdfY2lzc2Eocl9mZnQsDQogICAgICAgICAgICAgICAgICAgICAgZ3JvdXBzID0gbGlzdCgNCiAgICAgICAgICAgICAgICAgICAgICAgIGUgPSBjKDAsIDEvMTItZXBzLWVwcyksDQogICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX3NpbiA9IGMoMS8xMi1lcHMsIDEvMTIrZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfY29zID0gYygxLzMtZXBzLCAxLzMrZXBzKQ0KICAgICAgICAgICAgICAgICAgICAgICkNCiAgICAgICAgICAgICAgICAgICAgICApJHRfc2VyaWVzDQogIA0KICByX2ZmdF9leHRlbmRlZCA8LSByZWNvbnN0cnVjdF9mZnQoeFsxOihuLTEpXSwgeVsxOihuLTEpXSwgVFJVRSkNCiAgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCA8LSBncm91cGluZ19jaXNzYShyX2ZmdF9leHRlbmRlZCwNCiAgICAgICAgICAgICAgICAgICAgICBncm91cHMgPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgICAgICAgZSA9IGMoMCwgMS8xMi1lcHMtZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9jb3MgPSBjKDEvMy1lcHMsIDEvMytlcHMpDQogICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICAgICkkdF9zZXJpZXMNCiAgDQogIA0KICByX2Npc3NhIDwtIGNpcmN1bGFudF9TU0EoeSwgTCsxKQ0KICByX2Npc3NhX2dyb3VwZWQgPC0gZ3JvdXBpbmdfY2lzc2Eocl9jaXNzYSwNCiAgICAgICAgICAgICAgICAgICAgICBncm91cHMgPSBsaXN0KA0KICAgICAgICAgICAgICAgICAgICAgICAgZSA9IGMoMCwgMS8xMi1lcHMtZXBzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgIHNlc29uYWxfc2luID0gYygxLzEyLWVwcywgMS8xMitlcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9jb3MgPSBjKDEvMy1lcHMsIDEvMytlcHMpDQogICAgICAgICAgICAgICAgICAgICAgKQ0KICAgICAgICAgICAgICAgICAgICAgICkkdF9zZXJpZXMNCiAgDQogIA0KICByX2Npc3NhX2V4dCA8LSBjaXJjdWxhbnRfU1NBKHksIEwrMSwgZXh0ZW5kX2ZsYWcgPSBUUlVFKQ0KICByX2Npc3NhX2dyb3VwZWRfZXh0IDwtIGdyb3VwaW5nX2Npc3NhKHJfY2lzc2FfZXh0LA0KICAgICAgICAgICAgICAgICAgICAgIGdyb3VwcyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgICBlID0gYygwLCAxLzEyLWVwcy1lcHMpLA0KICAgICAgICAgICAgICAgICAgICAgICAgc2Vzb25hbF9zaW4gPSBjKDEvMTItZXBzLCAxLzEyK2VwcyksDQogICAgICAgICAgICAgICAgICAgICAgICBzZXNvbmFsX2NvcyA9IGMoMS8zLWVwcywgMS8zK2VwcykNCiAgICAgICAgICAgICAgICAgICAgICApDQogICAgICAgICAgICAgICAgICAgICAgKSR0X3Nlcmllcw0KICANCiAgDQogIA0KICBkYXRhJGNvc19lcnJbWzFdXVtbaV1dIDwtIG1zZSh5MSwgcl9zc2Ekc2Vzb25hbF9zaW4pDQogIGRhdGEkc2luX2VycltbMV1dW1tpXV0gPC0gbXNlKHkyLCByX3NzYSRzZXNvbmFsX2NvcykNCiAgZGF0YSRleHBfZXJyW1sxXV1bW2ldXSA8LSBtc2UoeTMsIHJfc3NhJGUpDQogIGRhdGEkYWxsX2VycltbMV1dW1tpXV0gPC0gbXNlKHkxICsgeTIgKyB5MywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcl9zc2Ekc2Vzb25hbF9zaW4rDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcl9zc2Ekc2Vzb25hbF9jb3MgKw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJfc3NhJGUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICANCiAgZGF0YSRjb3NfZXJyW1syXV1bW2ldXSA8LSBtc2UoeTEsIHJfc3NhX2Ukc2Vzb25hbF9zaW4pDQogIGRhdGEkc2luX2VycltbMl1dW1tpXV0gPC0gbXNlKHkyLCByX3NzYV9lJHNlc29uYWxfY29zKQ0KICBkYXRhJGV4cF9lcnJbWzJdXVtbaV1dIDwtIG1zZSh5Mywgcl9zc2FfZSRlKQ0KICBkYXRhJGFsbF9lcnJbWzJdXVtbaV1dIDwtIG1zZSh5MSArIHkyICsgeTMsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJfc3NhX2Ukc2Vzb25hbF9zaW4rIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJfc3NhX2Ukc2Vzb25hbF9jb3MgKyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByX3NzYV9lJGUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICANCiAgDQogICMgcHJpbnQoZGF0YSRzaW5fZXJyW1syXV1bW2ldXSkNCiAgDQogIA0KICBkYXRhJGNvc19lcnJbWzNdXVtbaV1dIDwtIG1zZSh5MVsxOihuLTEpXSwgcl9mZnRfZ3JvdXBlZCRzZXNvbmFsX3NpbikNCiAgZGF0YSRzaW5fZXJyW1szXV1bW2ldXSA8LSBtc2UoeTJbMToobi0xKV0sIHJfZmZ0X2dyb3VwZWQkc2Vzb25hbF9jb3MpDQogIGRhdGEkZXhwX2VycltbM11dW1tpXV0gPC0gbXNlKHkzWzE6KG4tMSldLCByX2ZmdF9ncm91cGVkJGUpDQogIGRhdGEkYWxsX2VycltbM11dW1tpXV0gPC0gbXNlKCh5MSArIHkyICsgeTMpWzE6KG4tMSldLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByX2ZmdF9ncm91cGVkJHNlc29uYWxfc2luICsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByX2ZmdF9ncm91cGVkJHNlc29uYWxfY29zICsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByX2ZmdF9ncm91cGVkJGUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICANCiAgDQogIGRhdGEkY29zX2VycltbNF1dW1tpXV0gPC0gbXNlKHkxLCByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9zaW4pDQogIGRhdGEkc2luX2VycltbNF1dW1tpXV0gPC0gbXNlKHkyLCByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9jb3MpDQogIGRhdGEkZXhwX2VycltbNF1dW1tpXV0gPC0gbXNlKHkzLCByX2Npc3NhX2dyb3VwZWQkZSkNCiAgZGF0YSRhbGxfZXJyW1s0XV1bW2ldXSA8LSBtc2UoeTEgKyB5MiArIHkzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByX2Npc3NhX2dyb3VwZWQkc2Vzb25hbF9zaW4gKw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJfY2lzc2FfZ3JvdXBlZCRzZXNvbmFsX2NvcyArDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcl9jaXNzYV9ncm91cGVkJGUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQ0KICANCiAgDQogIGRhdGEkY29zX2VycltbNV1dW1tpXV0gPC0gbXNlKHkxLCByX2Npc3NhX2dyb3VwZWRfZXh0JHNlc29uYWxfc2luKQ0KICBkYXRhJHNpbl9lcnJbWzVdXVtbaV1dIDwtIG1zZSh5Miwgcl9jaXNzYV9ncm91cGVkX2V4dCRzZXNvbmFsX2NvcykNCiAgZGF0YSRleHBfZXJyW1s1XV1bW2ldXSA8LSBtc2UoeTMsIHJfY2lzc2FfZ3JvdXBlZF9leHQkZSkNCiAgZGF0YSRhbGxfZXJyW1s1XV1bW2ldXSA8LSBtc2UoeTEgKyB5MiArIHkzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByX2Npc3NhX2dyb3VwZWRfZXh0JHNlc29uYWxfc2luICsgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcl9jaXNzYV9ncm91cGVkX2V4dCRzZXNvbmFsX2NvcyArDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcl9jaXNzYV9ncm91cGVkX2V4dCRlDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkNCiAgDQogIGRhdGEkY29zX2VycltbNl1dW1tpXV0gPC0gbXNlKHkxWzE6KG4tMSldLCByX2ZmdF9ncm91cGVkX2V4dGVuZGVkJHNlc29uYWxfc2luKQ0KICBkYXRhJHNpbl9lcnJbWzZdXVtbaV1dIDwtIG1zZSh5MlsxOihuLTEpXSwgcl9mZnRfZ3JvdXBlZF9leHRlbmRlZCRzZXNvbmFsX2NvcykNCiAgZGF0YSRleHBfZXJyW1s2XV1bW2ldXSA8LSBtc2UoeTNbMToobi0xKV0sIHJfZmZ0X2dyb3VwZWRfZXh0ZW5kZWQkZSkNCiAgZGF0YSRhbGxfZXJyW1s2XV1bW2ldXSA8LSBtc2UoKHkxICsgeTIgKyB5MylbMToobi0xKV0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJfZmZ0X2dyb3VwZWRfZXh0ZW5kZWQkc2Vzb25hbF9zaW4gKw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJfZmZ0X2dyb3VwZWRfZXh0ZW5kZWQkc2Vzb25hbF9jb3MgKw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJfZmZ0X2dyb3VwZWRfZXh0ZW5kZWQkZQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApDQp9DQpsaWJyYXJ5KHh0YWJsZSkNCiMgZGF0YSRzaW5fZXJyW1syXV0NCiMg0KjQsNCzIDI6INCh0L7Qt9C00LDQvdC40LUg0L/RgNC40LzQtdGA0LAg0LTQsNC90L3Ri9GFDQpkYXRhX3ByZXYgPC0gZGF0YQ0KZGF0YSA8LSBkYXRhLmZyYW1lKA0KICDQnNC10YLQvtC0ID0gYygiU1NBIiwgIlNTQSBFT1NTQSIsIkZvdXJpZXIiLCAiQ2lTU0EiLCAiQ2lTU0EgZXh0ZW5kZWQiLCAiRm91cmllciBleHRlbmRlZCIpLA0KICBleHBfZXJyID0gYygwLCAwLCAwLCAwLCAwLCAwKSwNCiAgc2luX2VyciA9IGMoMCwgMCwgMCwgMCwgMCwgMCksDQogIGNvc19lcnIgPSBjKDAsIDAsIDAsIDAsIDAsIDApLA0KICBhbGxfZXJyID0gYygwLCAwLCAwLCAwLCAwLCAwKQ0KKQ0KDQpkYXRhJGNvc19lcnJbMV0gPC0gbWVhbihkYXRhX3ByZXYkY29zX2VycltbMV1dIHw+IHVubGlzdCgpKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkc2luX2VyclsxXSA8LSBtZWFuKGRhdGFfcHJldiRzaW5fZXJyW1sxXV18PiB1bmxpc3QoKSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGV4cF9lcnJbMV0gPC0gbWVhbihkYXRhX3ByZXYkZXhwX2VycltbMV1dfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzFdIDwtIG1lYW4oZGF0YV9wcmV2JGFsbF9lcnJbWzFdXXw+IHVubGlzdCgpKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCg0KDQpkYXRhJGNvc19lcnJbMl0gPC0gbWVhbihkYXRhX3ByZXYkY29zX2VycltbMl1dfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzJdIDwtIG1lYW4oZGF0YV9wcmV2JHNpbl9lcnJbWzJdXXw+IHVubGlzdCgpKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkZXhwX2VyclsyXSA8LSBtZWFuKGRhdGFfcHJldiRleHBfZXJyW1syXV18PiB1bmxpc3QoKSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbMl0gPC0gbWVhbihkYXRhX3ByZXYkYWxsX2VycltbMl1dfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQoNCmRhdGEkY29zX2VyclszXSA8LSBtZWFuKGRhdGFfcHJldiRjb3NfZXJyW1szXV18PiB1bmxpc3QoKSkgfD4gDQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzNdIDwtIG1lYW4oZGF0YV9wcmV2JHNpbl9lcnJbWzNdXXw+IHVubGlzdCgpKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGV4cF9lcnJbM10gPC0gbWVhbihkYXRhX3ByZXYkZXhwX2VycltbM11dfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzNdIDwtIG1lYW4oZGF0YV9wcmV2JGFsbF9lcnJbWzNdXXw+IHVubGlzdCgpKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCg0KDQpkYXRhJGNvc19lcnJbNF0gPC0gbWVhbihkYXRhX3ByZXYkY29zX2VycltbNF1dfD4gdW5saXN0KCkpIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkc2luX2Vycls0XSA8LSBtZWFuKGRhdGFfcHJldiRzaW5fZXJyW1s0XV18PiB1bmxpc3QoKSkgfD4gDQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRleHBfZXJyWzRdIDwtIG1lYW4oZGF0YV9wcmV2JGV4cF9lcnJbWzRdXXw+IHVubGlzdCgpKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkYWxsX2Vycls0XSA8LSBtZWFuKGRhdGFfcHJldiRhbGxfZXJyW1s0XV18PiB1bmxpc3QoKSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQoNCmRhdGEkY29zX2Vycls1XSA8LSBtZWFuKGRhdGFfcHJldiRjb3NfZXJyW1s1XV18PiB1bmxpc3QoKSkgfD4gDQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRzaW5fZXJyWzVdIDwtIG1lYW4oZGF0YV9wcmV2JHNpbl9lcnJbWzVdXXw+IHVubGlzdCgpKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGV4cF9lcnJbNV0gPC0gbWVhbihkYXRhX3ByZXYkZXhwX2VycltbNV1dfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KZGF0YSRhbGxfZXJyWzVdIDwtIG1lYW4oZGF0YV9wcmV2JGFsbF9lcnJbWzVdXXw+IHVubGlzdCgpKSB8Pg0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCg0KZGF0YSRjb3NfZXJyWzZdIDwtIG1lYW4oZGF0YV9wcmV2JGNvc19lcnJbWzZdXXw+IHVubGlzdCgpKSB8PiANCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJHNpbl9lcnJbNl0gPC0gbWVhbihkYXRhX3ByZXYkc2luX2VycltbNl1dfD4gdW5saXN0KCkpIHw+IA0KICBmb3JtYXRDKGZvcm1hdCA9ICJlIiwgZGlnaXRzID0gMSkNCmRhdGEkZXhwX2Vycls2XSA8LSBtZWFuKGRhdGFfcHJldiRleHBfZXJyW1s2XV18PiB1bmxpc3QoKSkgfD4NCiAgZm9ybWF0Qyhmb3JtYXQgPSAiZSIsIGRpZ2l0cyA9IDEpDQpkYXRhJGFsbF9lcnJbNl0gPC0gbWVhbihkYXRhX3ByZXYkYWxsX2VycltbNl1dfD4gdW5saXN0KCkpIHw+DQogIGZvcm1hdEMoZm9ybWF0ID0gImUiLCBkaWdpdHMgPSAxKQ0KDQpgYGANCg0KYGBge3J9DQpmb3IgKGkgaW4gMTo2KXsNCiAgZm9yIChqIGluIChpKTo2KXsNCiAgICB4IDwtIGRhdGFfcHJldiRjb3NfZXJyW1tpXV0gfD4gdW5saXN0KCkNCiAgICB5IDwtIGRhdGFfcHJldiRjb3NfZXJyW1tqXV0gfD4gdW5saXN0KCkNCiAgICB0X3Rlc3RfcmVzdWx0IDwtIHQudGVzdCh4LCB5LCBwYWlyZWQgPSBUUlVFKQ0KICAgIGlmICghaXMubmEodF90ZXN0X3Jlc3VsdCRwLnZhbHVlKSAmIHRfdGVzdF9yZXN1bHQkcC52YWx1ZSA+IDAuMDUpew0KICAgICAgcHJpbnQocGFzdGUoImNvcywgIiwgZGF0YSTQnNC10YLQvtC0W2ldLCAiICIsDQogICAgICAgICAgICAgICAgICBkYXRhJNCc0LXRgtC+0LRbal0sICIsIHAtdmFsID0gIiwgdF90ZXN0X3Jlc3VsdCRwLnZhbHVlKSkNCiAgICAgIH0NCiAgfQ0KfQ0KDQpmb3IgKGkgaW4gMTo2KXsNCiAgZm9yIChqIGluIChpKTo2KXsNCiAgICB4IDwtIGRhdGFfcHJldiRzaW5fZXJyW1tpXV0gfD4gdW5saXN0KCkNCiAgICB5IDwtIGRhdGFfcHJldiRzaW5fZXJyW1tqXV0gfD4gdW5saXN0KCkNCiAgICB0X3Rlc3RfcmVzdWx0IDwtIHQudGVzdCh4LCB5LCBwYWlyZWQgPSBUUlVFKQ0KICAgIGlmICghaXMubmEodF90ZXN0X3Jlc3VsdCRwLnZhbHVlKSAmIHRfdGVzdF9yZXN1bHQkcC52YWx1ZSA+IDAuMDUpew0KICAgICAgcHJpbnQocGFzdGUoInNpbiwgIiwgZGF0YSTQnNC10YLQvtC0W2ldLCAiICIsIGRhdGEk0JzQtdGC0L7QtFtqXSwgIiwgcC12YWwgPSAiLCB0X3Rlc3RfcmVzdWx0JHAudmFsdWUpKQ0KICAgICAgfQ0KICB9DQp9DQoNCmZvciAoaSBpbiAxOjYpew0KICBmb3IgKGogaW4gKGkpOjYpew0KICAgIHggPC0gZGF0YV9wcmV2JGV4cF9lcnJbW2ldXSB8PiB1bmxpc3QoKQ0KICAgIHkgPC0gZGF0YV9wcmV2JGV4cF9lcnJbW2pdXSB8PiB1bmxpc3QoKQ0KICAgIHRfdGVzdF9yZXN1bHQgPC0gdC50ZXN0KHgsIHksIHBhaXJlZCA9IFRSVUUpDQogICAgaWYgKCFpcy5uYSh0X3Rlc3RfcmVzdWx0JHAudmFsdWUpICYgdF90ZXN0X3Jlc3VsdCRwLnZhbHVlID4gMC4wNSl7DQogICAgICBwcmludChwYXN0ZSgiZXhwLCAiLCBkYXRhJNCc0LXRgtC+0LRbaV0sICIgIiwgZGF0YSTQnNC10YLQvtC0W2pdLCAiLCBwLXZhbCA9ICIsIHRfdGVzdF9yZXN1bHQkcC52YWx1ZSkpfQ0KICB9DQp9DQoNCmZvciAoaSBpbiAxOjYpew0KICBmb3IgKGogaW4gKGkpOjYpew0KICAgIHggPC0gZGF0YV9wcmV2JGFsbF9lcnJbW2ldXSB8PiB1bmxpc3QoKQ0KICAgIHkgPC0gZGF0YV9wcmV2JGFsbF9lcnJbW2pdXSB8PiB1bmxpc3QoKQ0KICAgIHRfdGVzdF9yZXN1bHQgPC0gdC50ZXN0KHgsIHksIHBhaXJlZCA9IFRSVUUpDQogICAgaWYgKCFpcy5uYSh0X3Rlc3RfcmVzdWx0JHAudmFsdWUpICYgdF90ZXN0X3Jlc3VsdCRwLnZhbHVlID4gMC4wNSl7DQogICAgICBwcmludChwYXN0ZSgiYWxsX2VyciwgIiwgZGF0YSTQnNC10YLQvtC0W2ldLCAiICIsIGRhdGEk0JzQtdGC0L7QtFtqXSwgIiwgcC12YWwgPSAiLCB0X3Rlc3RfcmVzdWx0JHAudmFsdWUpKQ0KICAgICAgfQ0KICB9DQp9DQoNCg0KdGFibGVfbGF0ZXggPC0geHRhYmxlKGRhdGEsIGNhcHRpb24gPSAiRXhhbXBsZSBUYWJsZSIpDQoNCiMg0KjQsNCzIDQ6INCS0YvQstC+0LQg0YLQsNCx0LvQuNGG0Ysg0LIgTGFUZVgg0YTQsNC50LsNCnByaW50KHRhYmxlX2xhdGV4LCBpbmNsdWRlLnJvd25hbWVzID0gRkFMU0UpDQpgYGANCg==